매개변수 객체 만들기 Introduce Parameter Object

0

리팩터링 카탈로그

목록 보기
8/10

배경


데이터 항목 여러 개가 이 함수에서 저 함수로 함꼐 몰려다니는 경우를 자주 본다. 나는 이런 데이터 무리를 발견하면 데이터 구조 하나로 모아주곤 한다.

데이터 뭉치를 데이터 구조로 묶으면 데이터 사이의 관계가 명확해진다는 이점을 얻느낟. 게다가 함수가 이 데이터 구조를 받게 하면 매개변수 수가 줄아든다. 같은 데이터 구조를 사용하는 모든 함수가 원소를 참조할 때 항상 똑같은 이름을 사용하기 때문에 일고나성도 높여준다.

하지만 이 리펙터링의 진정한 힘은 코드를 더 근본적으로 바꿔준다는 데 있다. 나는 이런 데이터 구조를 새로 발견하면 이 데이터 구조를 활용하는 형태로 프로그램 동작을 재구성한다. 데티어 구조에 담길 데이터에 공통으로 적용되는 동작을 추출하여 함수로 만드는 것이다(공용 함수를 나열하는 식으로 작성할 수도 있고, 이 함수들과 데이터를 합쳐 클래스로 만들 수도 있다). 이 과정에서 새로 만든 데이터 구조가 문제 영역을 훨씬 간결하게 표현하는 새로운 추상개념으로 격상되면서, 코드의 개념적인 그림을 다시 그릴 수도 있다. 그러면 놀라울 정도로 강력한 효과를 낸다. 하지만 이 모든 것의 시작은 매개변수 객체 만들기부터다.

절차


  1. 적당한 데이터 구조가 아직 마련되어 있지 않다면 새로 만든다.
  • 개인적으로 클래스로 만드는 것을 선호한다. 나중에 동작까지 하몎 묶기 좋기 때문이다. 나는 주로 데이터 구조를 값 객체로 만든다.
  1. 테스트한다
  2. 함수 선언 바꾸기로 새 데이터 구조를 매개변수로 추가한다.
  3. 테스트한다.
  4. 함수 호출 시 새로운 데이터 구조 인스턴스를 넘기도록 수정한다. 하나씩 수정할 때마다 테스트한다.
  5. 기존 매개변수를 사용하던 코드를 새 데이터 구조의 원소를 사용하도록 바꾼다.
  6. 다 바꿨다면 기존 매개변수를 제거하고 테스트한다.

예시


before

const station = {
	name: "281",
    readings: [
      {temp: 47, time: "2021-12-10 09:10"},
      {temp: 53, time: "2021-12-10 09:10"},
      {temp: 58, time: "2021-12-10 09:10"},
      {temp: 41, time: "2021-12-10 09:10"},
      {temp: 42, time: "2021-12-10 09:10"},
      {temp: 48, time: "2021-12-10 09:10"},
    ]
};

function readingOutsideRange(station, min, max) {
	return station.readings.filter(r =>
                                   r.temp < min || r.temp >max);
}
alerts = readingsOutsideRange(station, 	
                              operatingPlan.temperatureFloor, 
                              operatingPlan.temperatureCelling);

after

class NumberRange {
	constructor(min, max) {
    	this._data = {min: min, max: max};
    }
    get min() {return this._data.min;}
    get max() {return this._data.max;}
}
const range = new NumberRange(operatingPlan.temperatureFloor, 
                              operatingPlan.temperatureCelling);

function readingsOutsideRange(station, range) {
    return station.readings
          .filter(r => r.temp < range.min|| r.temp > range.max);
}

alerts = readingsOutsideRange(station, range);


  

출처


마틴 파울러 저 리팩터링 2판

0개의 댓글