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

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

ebook-product.kyobobook.co.kr

개요

클래스는 대다수 언어가 제공하는 기본적인 빌딩 블록

클래스는 데이터와 함수를 하나의 공유 환경으로 묶어 그중 일부를 외부에 제공한다.

 

함수 호출 인수로 전달되는 공통 데이터를 중심으로 작동하는 함수들을 클래스 하나로 묶는다.

클래스로 묶으면 함수들 공통 환경을 명확히 표현할 있다.

 

클래스로 묶을 장점은 클라이언트가 객체의 핵심 데이터를 변경할 있고, 파생 객체들을 일관되게 관리할 있다.

 

함수들을 중첩함수로 묶는도 되지만, 클래스를 지원하는 언어라면 클래스로 묶는다.

만약 클래스를 지원하지 않는 언어라는 '함수를 객체처럼 패턴' 사용을 고려한다.

//함수를 객체처럼
function Cat(name){
    return {
        name : name,
        getName : function(){return name;},
        setName : function(arg){name=arg},
        sound : function(){sound(name);}
    };
    function sound(name){console.log(name + " 냐아아아옹");}
}
var cat = Cat('나비');
cat.sound();
cat.setName('배추나비');
cat.sound();
///
나비 냐아아아옹
배추나비 냐아아아옹

 

예시

마시는 차를 정부에서 수돗물처럼 제공한다고 가정, 계량기를 읽어서 측정값을 기록 계산하는 코드

//측정값
let reading={customer : "ivan", quantity:10, month:5, uear:2017};
//클라이언트1
const aReading = acquireReading();
const baseCharge = baseRate(aReading.month, aReading.year) * aReading.quantity;
//클라이언트2
const aReading2 = acquireReading();
const baseCharge2 = baseRate(aReading2.month, aReading2.year) * aReading2.quantity;
const taxableCharge2 = Math.max(0,base-taxTreshold(aReading2.year));
//클라이언트3
const aReading3 = acquireReading();
const basicChargeAmount3 = calculateBaseCharge(aReading3);
function calculateBaseCharge(aReading){
    return baseRate(aReading.month, aReading.year);
}
//레코드를 클래스로 캡슐화
class Reading{
    constructor(data){
        this._customer = data.customer;
        this._quantity = data.quantity;
        this._month = data.month;
        this._year = data.year;
    }
    get customer(){return this._customer;}
    get quantity(){return this._quantity;}
    get month(){return this._month;}
    get year(){return this._year;}
}


//클라이언트3
const rawReading = acquireReading();
const aReading3 = new Reading(rawReading);
const basicChargeAmount = aReading3.calculateBaseCharge;
//레코드를 클래스로 캡슐화
class Reading{
    constructor(data){
        this._customer = data.customer;
        this._quantity = data.quantity;
        this._month = data.month;
        this._year = data.year;
    }
    get customer(){return this._customer;}
    get quantity(){return this._quantity;}
    get month(){return this._month;}
    get year(){return this._year;}
    //함수 옮김
    get calculateBaseCharge(){
        return baseRate(this.month, this.year);
    }
}
const rawReading = acquireReading();
const aReading3 = new Reading(rawReading);
const basicChargeAmount = aReading3.baseCharge;
class Reading{
    constructor(data){
        this._customer = data.customer;
        this._quantity = data.quantity;
        this._month = data.month;
        this._year = data.year;
    }
    get customer(){return this._customer;}
    get quantity(){return this._quantity;}
    get month(){return this._month;}
    get year(){return this._year;}
    //알맞은 이름 짓기
    get baseCharge(){
        return baseRate(this.month, this.year);
    }
}
//클라이언트1
const rawReading = acquireReading();
const aReading = new Reading(rawReading);
const baseCharge = aReading.baseRate;


//클라이언트2
const rawReading2 = acquireReading();
const aReading2 = new Reading(rawReading);
const taxableCharge2 = Math.max(0,aReading2.baseRate-taxTreshold(aReading2.year));


//클라이언트는 aReading.baseRate  이렇게 호출한다.
이게 필드인지 함수호출로 계산된 값인지 구분할 수없다. 이를 단일 접근 원칙이라 한다.
//클라이언트2
const rawReading2 = acquireReading();
const aReading2 = new Reading(rawReading);
const taxableCharge2 = taxableChargeFn() ;
//함수로 추출
function taxableChargeFn() {
    return Math.max(0, aReading2.baseRate - taxTreshold(aReading2.year));
}


//측정값
let reading={customer : "ivan", quantity:10, month:5, uear:2017};
//클라이언트1
const rawReading = acquireReading();
const aReading = new Reading(rawReading);
const baseCharge = aReading.baseRate;
//클라이언트2
const rawReading2 = acquireReading();
const aReading2 = new Reading(rawReading);
const taxableCharge2 = aReading2.taxableCharge;
//클라이언트3
const rawReading3 = acquireReading();
const aReading3 = new Reading(rawReading3);
const basicChargeAmount = aReading3.baseCharge;
class Reading{
    constructor(data){
        this._customer = data.customer;
        this._quantity = data.quantity;
        this._month = data.month;
        this._year = data.year;
    }
    get customer(){return this._customer;}
    get quantity(){return this._quantity;}
    get month(){return this._month;}
    get year(){return this._year;}
    get baseCharge(){
        return baseRate(this.month, this.year);
    }
    get taxableCharge() {
        return Math.max(0, this.baseRate - taxTreshold(aReading2.year));
    }
}

+ Recent posts