리팩터링 | 마틴 파울러 | 한빛미디어- 교보ebook

코드 구조를 체계적으로 개선하여 효율적인 리팩터링 구현하기, 20여 년 만에 다시 돌아온 마틴 파울러의 리팩터링 2판 리팩터링 1판은 1999년 출간되었으며, 한국어판은 2002년 한국에 소개되었다

ebook-product.kyobobook.co.kr

개요

개발 초기엔 단순한 정보 표현을 위한 숫자나 문자열이 시간이 지남에 따라 이상 단순해지지 않게 변한다.

전화번호의 경우 포매팅, 지역 코드 추출, 뒷자리 추출 암호화 특별한 동작이 필요해질 있다.

 

단순한 출력 이상의 기능이 필요해지는 순간 데이터를 표현하는 전용 클래스를 정의해야 한다.

 

예시



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;

 

 

 

 

 

 

 

 

 

+ Recent posts