본문 바로가기
JavaScript│Node js

마틴 파울러 - 리팩토링 - Extract Class

by 자유코딩 2019. 10. 31.

소스 코드에서 각 클래스의 책임과 역할은 명확해야 한다.

하나의 클래스가 여러 개의 책임과 역할을 가지고 있다면 리팩토링이 필요하다.

여러 개의 책임을 가지는 클래스를 리팩토링해본다.

 

순서는 이렇다.

1. 책임을 어떻게 분리할지 기준을 정한다.

2. 책임을 넘길 자식 클래스를 만든다. 부모 클래스가 할 역할이 바뀐다면 역할과 책임에 맞게 클래스 이름을 바꾼다. 

3. 부모클래스와 자식클래스를 연결할 때 자식 클래스의 인스턴스를 만든다.

4. 부모 클래스에서 자식 클래스로 옮길 변수들을 옮긴다.

5. 부모 클래스에서 자식 클래스로 옮길 함수들을 옮긴다.

6. 클래스, 함수 이름을 적절하게 바꾼다. 필요없는 함수는 지운다.

7. 새로운 자식 클래스를 더 만들어서 분리할지 결정한다.

 

코드를 통해서 단계를 살펴본다.

class Person {
	getName() { return this._name; }
    setName(args) { this._name = args; }
    getTelephoneNumber() { return `${this.officeAreaCode} ${this.officeNumber}`
	getOfficeAreaCode() { return this._officeAreaCode; }
    setOfficeAreaCode(args) { this.officeAreaCode = args; }
    getOfficeNumber() { return this._officeNumber; }
    setOfficeNumber(args) { this._officeNumber = args; }
}

사람 클래스인데 전화번호에 관한 코드가 많다.

그래서 전화 번호 클래스를 하나 만들고 데이터와 함수들을 옮겨본다.

 

class TelephoneNumber {
}

클래스를 만들었다면 Person 클래스에서 생성자를 만든다.

그리고 Person 클래스의 생성자에서 TelephoneNumber 클래스의 인스턴스를 만든다.

 

class Person {
	constructor() {
    	this._telephoneNumber = new TelephoneNumber();
    }
}

TelephoneNumber 클래스의 내용을 채운다.

class TelephoneNumber { 
	getOfficeAreaCode() { return this._officeAreaCode; }
    setOfficeAreaCode(args) { this._officeAreaCode = args; }
}

여기서 Person 클래스의 함수가 조금 바뀐다.

 

class Person { 
	getOfficeAreaCode() { return this._telephoneNumber.officeAreaCode; }
    setOfficeAreaCode(args) { this._telephoneNumbrer.officeAreaCode = args; }
}

Person 클래스의 생성자를 만드는 부분에서 _telephoneNumber 를 new TelephoneNumber()로 초기화 했었다.

초기화 한 _telephoneNumber를 getOfficeAreaCode() 같은 Person 클래스의 함수에서 사용한다.

 

TelephoneNumber 클래스의 함수 이름을 고친다.

class TelephoneNumber { 
	getOfficeNumber() { return this._officeNumber; }
    setOfficeNumber(args) { this._officeNumber = args; }
}

Person 클래스도 따라서 조금 바뀐다.

함수의 이름을 고쳤다.

class Person { 
	getOfficeNumber() { return this._telephoneNumber.officeNumber; }
    setOfficeNumber(args) { this._telephoneNumbrer.officeNumber = args; }
}

이제 함수의 이름을 리뷰한다.

Telephone 클래스의 officeNumber는 적절하지 않은듯 하다.

전화번호 클래스라면 지역번호 같은 표현은 맞겠지만 사무실 번호라는 표현은 맞지 않는다.

 

TelephoneNumber 클래스와 Person 클래스 모두 함수의 이름을 변경한다.

 

class TelephoneNumber { 
	getAreaCode() { return this._areaCode; }
    setAreaCode(args) { this._areaCode = args; }
    getNumber() { return this._number; }
    setNumber(args) { this._number = args; }
}
class Person { 
	getOfficeAreaCode() { return this._telephoneNumber.areaCode; }
    setOfficeAreaCode(args) { this._telephoneNumber.areaCode = args; }
    getOfficeNumber() { return this._telephoneNumber.number; }
    setOfficeNumber(args) { this._telephoneNumber.number = args; }
}

 

 

 

 

 

 

댓글