개요
개발 초기엔 단순한 정보 표현을 위한 숫자나 문자열이 시간이 지남에 따라 더 이상 단순해지지 않게 변한다.
전화번호의 경우 포매팅, 지역 코드 추출, 뒷자리 추출 암호화 등 특별한 동작이 필요해질 수 있다.
단순한 출력 이상의 기능이 필요해지는 순간 그 데이터를 표현하는 전용 클래스를 정의해야 한다.
예시
class Order{ constructor(data){ this.priority = data.priority; } } //클라이언트 let highPriorityCount = orders.filter(o => "high" === o.priority || "rush" === o.priority) .length; |
class Order{ constructor(data){ this._priority = data.priority; } //변수부터 캡슐화, 나중에 필드 이름이 변경되도 클라이언트 코드는 유지된다. get priority(){return this._priority;} set priority(arg){this._priority = arg;} } |
//우선순위 속성을 표현하는 값 클래스 정의 class Priority{ constructor(value){ this._value = value; } //get value() 가 아닌 변환함수 사용 toString(){return this._value;} } |
class Order{ constructor(data){ this._priority = data.priority; } //정의한 클래스 사용하도록 변경 get priority(){return this._priority.toString();} set priority(aString){this._priority = new Priority(aString);} } |
//우선순위 자체가 아닌 우선순위를 표현하는 문자열 표현 class Order{ constructor(data){ this._priority = data.priority; } get priorityString(){return this._priority.toString();} set priority(aString){this._priority = new Priority(aString);} } class Priority{ constructor(value){ this._value = value; } toString(){return this._value;} } let highPriorityCount = orders.filter(o => "high" === o.priorityString || "rush" === o.priorityString) .length; |
추가 리팩터링
//Priority 클래스를 직접 사용하는 것이 좋을 것 같아 추가 개선 class Order{ constructor(data){ this._priority = data.priority; } get priority(){return this._priority;} get priorityString(){return this._priority.toString();} set priority(aString){this._priority = new Priority(aString);} } class Priority{ constructor(value){ if(value instanceof Priority) return value; if(Priority.legalValues().includes(value)) this._value = value; else throw new Error(`<${value}>는 요효하지 않은 우선순위입니다.`); } toString(){return this._value;} get _index(){return Priority.legalValues().findIndex(s=>s===this._value);} static legalValues(){return ['low','normal','high','rush'];} equals(other){return this._index === other._index;} higherThan(other){return this._index > other._index;} lowerThan(other){return this._index < other._index;} compareTo(other){return this._index - other._index;} } let highPriorityCount = orders.filter(o => o.priority.higherThan(new Priority("normal"))) .length; |
'IT책, 강의 > 리팩터링' 카테고리의 다른 글
07 - 캡슐화 - 클래스 인라인하기 (0) | 2023.07.29 |
---|---|
07 - 캡슐화 - 임시 변수를 질의 함수로 바꾸기 (1) | 2023.07.28 |
07 - 캡슐화 - 컬렉션 캡슐화하기 (0) | 2023.07.26 |
07 - 캡슐화 - 레코드 캡슐화하기 (0) | 2023.07.25 |
06 - 기본적인 리펙터링 - 단계 쪼개기 (0) | 2023.07.24 |