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 | 29 | 30 | 31 |
Tags
- table not found
- PersistenceContext
- JanusWebRTC
- 코루틴 빌더
- vfr video
- pytest
- 헥사고날아키텍처 #육각형아키텍처 #유스케이스
- tolerated
- 겨울 부산
- mp4fpsmod
- 달인막창
- 자원부족
- JanusGateway
- JanusWebRTCServer
- Spring Batch
- taint
- python
- k8s #kubernetes #쿠버네티스
- 개성국밥
- 오블완
- PytestPluginManager
- VARCHAR (1)
- Value too long for column
- 코루틴 컨텍스트
- JanusWebRTCGateway
- preemption #
- kotlin
- 깡돼후
- 티스토리챌린지
- terminal
Archives
너와 나의 스토리
[리팩터링] 슈퍼클래스 추출하기 Extract Superclass 본문
반응형
배경
- 비슷한 일을 수행하는 두 클래스가 보이면 상속 메커니즘을 이용해서 비슷한 부분을 공통의 슈퍼클래스로 옮겨 담을 수 있다.
- 슈퍼클래스 추출하기의 대안으로는 클래스 추출하기가 있다.
- 어느 것을 선택하느냐는 중복 동작을 상속으로 해결하느냐 위임으로 해결하느냐에 달렸다.
- 슈퍼클래스 추출하기 방법이 더 간단할 경우가 많으니 이 리팩터링을 먼저 시도해보길 권한다.
절차
- 빈 슈퍼클래스를 만든다. 원래의 클래스들이 새 클래스를 상속하도록 한다.
- 테스트한다.
- 생성자 본문 올리기, 메서드 올리기, 필드 올리기를 차례로 적용하여 공통 원소를 슈퍼클래스로 옮긴다.
- 서브클래스에 남은 메서드들을 검토한다. 공통되는 부분이 있다면 함수로 추출한 다음 메서드 올리기를 적용한다.
- 원래 클래스들을 사용하는 코드를 검토하여 슈퍼클래스의 인터페이스를 사용하게 할지 고민해본다.
예시
- 다음 두 클래스를 사용하고 있는데, 공통된 기능이 눈에 띈다.
-
class Employee { constructor(name, id, monthlyCost) { this._id = id; this._name = name; this._monthlyCost = monthlyCost; } get monthlyCost() { return this._monthlyCost; } // 월간 비용 get name() { return this._name; } // 이름 get id() { return this._id; } get annualCost() { return this.monthlyCost * 12; } } class Department { constructor(name, staff) { this._name = name; this._staff = staff; } get staff() { return this._staff.slice(); } get name() { return this._name; } // 이름 get totalMonthlyCost() { return this.staff.map(e => e.monthlyCost) .reduce((sum, cost) => sum + cost); } get headCount() { return this.staff.length; } get totalAnnualCost() { return this.totalMonthlyCost * 12; } }
-
- 두 클래스로부터 슈퍼클래스를 추출해보자.
- [Step 1] 빈 슈퍼클래스를 만들고, 두 클래스가 이를 확장하도록 한다.
-
class Party { } class Employee extends Party { constructor(name, id, monthlyCost) { super(); this._id = id; this._name = name; this._monthlyCost = monthlyCost; } // ... } class Department extends Party { constructor(name, staff) { super(); this._name = name; this._staff = staff; } // ... }
-
- [Step 3] 데이터부터 슈퍼클래스(Party)로 올려주자.
- 먼저 이름 속성을 위로 올려보자.
-
class Party { constructor(name) { this._name = name; } } class Employee extends Party { constructor(name, id, monthlyCost) { super(name); this._id = id; this._monthlyCost = monthlyCost; } // ... } class Department extends Party { constructor(name, staff) { super(name); this._staff = staff; } // ... }
- 다음은 데이터와 관련된 메서드들을 옮겨보자.
-
class Party { constructor(name) { this._name = name; } get name() { return this._name; } }
-
// Employee 클래스 get name() {return this._name; }
// Department 클래스get name() {return this._name; } - 다음으로, 구현 로직이 비슷한 메서드가 두 개 보인다.
-
// Employee 클래스 get monthlyCost() { return this._monthlyCost; } get annualCost() { return this.monthlyCost * 12; } // Department 클래스 get totalMonthlyCost() { return this.staff.map(e => e.monthlyCost) .reduce((sum, cost) => sum + cost); } get totalAnnualCost() { return this.totalMonthlyCost * 12; }
- annualCost()와 totalAnnualCost() 이 두 메서드에서 호출하는 메서드는 이름도 다르고 본문 코드도 다르다.
- 하지만 의도는 같다. 그렇다면 함수 선언 바꾸기로 이름을 통일한다.
-
// Department 클래스 get annualCost() { // Before: totatlAnnualCost() return this.monthlyCost * 12; } get monthlyCost() {...} // Before: totalMonthlyCost()
- 이제 두 연간 비용 산출 메서드에 메서드 올리기를 적용할 수 있다.
-
Before After class Department {get totalAnnualCost() { }get name() { }get headCount() { }}
class Employee {get annualCost() { }get name() { }get id() { }}class Party {get name() { }get annualCost() { }}
class Department extends Party {get headCount() { }
get monthlyCost() { }}
class Employee extends Party {get id() { }
get monthlyCost() { }}
출처:
- [리팩터링 2판]
반응형
'개발 > Refactoring' 카테고리의 다른 글
[리팩터링] 오류 코드를 예외로 바꾸기 Replace Error Code with Exception (0) | 2022.02.09 |
---|---|
[리팩터링] 11.8 생성자를 팩터리 함수로 바꾸기 Replace Constructor with Factory Function (0) | 2022.01.25 |
[리팩터링] 11.5 매개변수를 질의 함수로 바꾸기 Replace parameter with Query (0) | 2022.01.18 |
[리팩터링] 특이 케이스 추가하기 Introduce Special Case (0) | 2022.01.02 |
[리팩토링] Replace Inline Code with Function Call 인라인 코드를 함수 호출로 바꾸기 (0) | 2021.11.20 |
Comments