Recent Posts
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- JanusGateway
- VARCHAR (1)
- python
- JanusWebRTCServer
- mp4fpsmod
- preemption #
- terminal
- pytest
- k8s #kubernetes #쿠버네티스
- 코루틴 빌더
- table not found
- PytestPluginManager
- 코루틴 컨텍스트
- Spring Batch
- 헥사고날아키텍처 #육각형아키텍처 #유스케이스
- 깡돼후
- kotlin
- 개성국밥
- PersistenceContext
- 자원부족
- 달인막창
- JanusWebRTCGateway
- 티스토리챌린지
- 겨울 부산
- Value too long for column
- vfr video
- tolerated
- taint
- 오블완
- JanusWebRTC
Archives
너와 나의 스토리
[리팩토링] Introduce Parameter Object 매개변수 객체 만들기 본문
반응형
function amountInvoiced(startDate, endDate) {...}
function amountEceived(startDate, endDate) {...}
function amountOverdue(startDate, endDate) {...}
function amountInvoiced(aDateRange) {...}
function amountEceived(aDateRange) {...}
function amountOverdue(aDateRange) {...}
- 데이터 항목 여러 개가 여러 함수에서 몰려다니는 경우를 자주 볼 수 있다.
- 이런 데이터 무리를 발견하면 데이터 구조 하나로 모아주면 좋다.
- 데이터 뭉치를 데이터 구조로 묶었을 때 장점
- 데이터 사이의 관계 명확
- 매개변수의 수가 줄어듦
- 일관성 높아짐
- 같은 데이터 구조를 사용하는 모든 함수가 원소를 참조할 때 항상 똑같은 이름을 사용하기 때문에
절차
- 적당한 데이터 구조가 아직 마련되어 있지 않다면 새로 만든다
- 클래스로 만드는 걸 추천
- 나중에 동작까지 함께 묶기 좋기 때문
- 주로 데이터 구조를 *값 객체(Value Object)로 만든다
- 클래스로 만드는 걸 추천
- 테스트
- 함수 선언 바꾸기로 새 데이터 구조를 매개변수로 추가
- 테스트
- 함수 호출 시 새로운 데이터 구조 인스턴스를 넘기도록 수정. 하나씩 수정할 때마다 테스트
- 기존 매개변수를 사용하던 코드를 새 데이터 구조의 원소를 사용하도록 바꿈
- 다 바꿨다면 기존 매개변수를 제거하고 테스트
값 객체(Value Object)
- 값을 전달하는 역할을 하는 객체
- 예: 좌표를 나타내는 두 개의 점 객체
- 이처럼 속성 값으로 인해 동일한 개체를 값 개체라고 한다.
- const p1 = {x: 2, y: 3}; const p2 = {x: 2, y: 3};
예시: 온도 측정값 배열에서 정상 작동 범위를 벗어난 것이 있는지 검사하는 코드를 살펴보자.
- 온도 측정값: reading
-
// 온도 측정값을 표현하는 데이터 const station = { name: "ZB1", readings: [ {temp: 47, time: "2016-11-10 09:10"}, {temp: 53, time: "2016-11-10 09:20"}, {temp: 58, time: "2016-11-10 09:30"}, {temp: 53, time: "2016-11-10 09:40"}, {temp: 51, time: "2016-11-10 09:50"}, ] }; // 정상 범위를 벗어난 측정값을 찾는 함수 function readingOutsideRange(station, min, max){ return station.readings .filter(r => r.temp < min || r.temp > max); } // 호출문 alerts = readingsOutsideRange(station, operatingPlan.temperatureFloor, // 최저 온도 operatingPlan.temperatureCeiling); // 최고 온도
- 호출 코드를 보면 최저 온도와 최고 온도를 각각 인자로 넘기고 있다.
- 이와 같은 범위는 객체 하나로 묶어서 표현하는 게 나은 대표적인 예다.
-
- Step 1: 데이터 뭉치를 클래스로 표현하기
-
class NumberRange { constructor(min, max){ this._data = {min: min, max: max}; } get min() {return this._data.min;} get max() {return this._data.max;} }
-
- Step 2: 테스트
- 현재 코드가 테스트 통과하는 코드임을 확인
- Step 3: 함수 선언 바꾸기로 새 데이터 구조를 매개변수로 추가
- 새로 만든 객체(NumberRange)를 매개변수로 추가하도록 함수 선언을 바꾼다.
- 호출문의 새 매개변수 자리에는 널을 넣어둔다.
-
// 정상 범위를 벗어난 측정값을 찾는 함수 function readingOutsideRange(station, min, max, range){ return station.readings .filter(r => r.temp < min || r.temp > max); } // 호출문 alerts = readingsOutsideRange(station, operatingPlan.temperatureFloor, // 최저 온도 operatingPlan.temperatureCeiling, // 최고 온도 null); // 범위
- Step 4: 테스트
- 아직 동작은 하나도 바꾸지 않아서 테스트는 문제없이 통과할 것.
- Step 5: 온도 범위를 객체 형태로 전달하도록 호출문을 하나씩 바꾼다.
-
const range = new NumberRange(operatingPlan.temperatureFloor, operatingPlan.temperatingCeiling); alerts = readingsOutsideRange(station, operatingPlan.temperatureFloor, // 최저 온도 operatingPlan.temperatureCeiling, // 최고 온도 range); // 범위
- 새로 건넨 매개변수(range)를 아직 사용하지 않았기 때문에 아직 동작은 바뀌지 않음.
- 즉, 아직까지는 테스트도 당연히 통과한다.
-
- Step 6: 기존 매개변수를 사용하는 부분을 변경
- 하나씩 차근차근 변경한다.
-
// 정상 범위를 벗어난 측정값을 찾는 함수 // 1. 최댓값 변경 function readingOutsideRange(station, min, max, range){ return station.readings .filter(r => r.temp < min || r.temp > range.max); } // 2. 최솟값 변경 function readingOutsideRange(station, min, max, range){ return station.readings .filter(r => r.temp < range.min || r.temp > range.max); }
- 한 번 더 테스트한 뒤 매개변수를 제거한다.
-
function readingOutsideRange(station, range){ return station.readings .filter(r => r.temp < range.min || r.temp > range.max); } // 호출문 alerts = readingsOutsideRange(station, range);
- Step 7: 마지막 테스트!
출처:
- Value Object: https://martinfowler.com/bliki/ValueObject.html
- [리팩터링 2판]
반응형
'개발 > Refactoring' 카테고리의 다른 글
[리팩토링] Extract Class 클래스 추출하기 (0) | 2021.11.01 |
---|---|
[리팩토링] Replace Primitive with Object 기본형을 객체로 바꾸기(데이터 항목 -> 객체) (0) | 2021.10.26 |
[리팩토링] Combine Functions into Transform 여러 함수를 변환 함수로 묶기 (0) | 2021.10.19 |
[리팩토링] Change Function Declaration 함수 선언 바꾸기 (0) | 2021.10.03 |
[리팩터링] Inline Function 예제로 이해하는 "함수 인라인하기" (0) | 2021.09.08 |
Comments