Generic Component(재사용 가능한 component)
소스 코드를 수정하거나 사소한 변경없이 다양한 컨텍스트에서 확장(extended), 조정(adapted) 및 재사용(reused)할 수 있는 프로그램 구성 요소. 객체 간 기능을 공유한다.
Refactoring이란?
반복되는 코드를 계속 사용하는 것이 아니라, 하나의 generic component로 만들어서 계속 사용하게 코드를 바꾸는 것이다. refactoring를 하면, 가독성을 높이고 유지보수를 쉽게 할 수 있게 도와준다.
Generalizing - 일반화
유사한 문제의 범주에 대한 특정 해결책의 재구성
Refactoring 과정
- 다양한 위치에서 중복 코드 세그먼트 식별
- 중복 logic을 generic component로 캡처
- 반복 코드 세그먼트가 발생할 때마다 generic component에 대한 참조로 바뀝니다.
Refactoring 효과
- 유지 관리 능력 향상
- 버그의 원인 제거(or localizing: 국지화)
Example of Refactoring
상속에 의한 refactoring. 사전에 부모 class에서 반복되는 component들을 하나의 component로 만들어, 자식 class에서는 해당 component를 호출하는 것만으로, 동일한 기능을 할 수 있습니다.
또한, 다음은 반복되는 component를 호출하는 component를 하나의 class 변수로 정의한 후, 필요한 경우에 따라 해당 변수를 호출하는 것으로 정의된 component를 refactoring할 수 있습니다.
Problems with Refactoring by Inheritance
만약 공통적인 부분이 밀접하게 관련되어 있다면 어떨까요?
class Common {
void commonCode1() {
/* common code segment 1 */
}
void commonCode2() {
/* common code segment 2 */
/* I want to modifie detail(version A, B) */
}
void commonCode3() {
/* common code segment 3 */
}
}
class ComputationA extend Common {
void commonCode2() {
/* common code segment 2 */
/* modified version A */
}
}
class ComputationB extend Common {
void commonCode2() {
/* common code segment 2 */
/* modified version B */
}
}
위와 같이 ComputationA, B에서 commonCode2 method의 detail을 조금만 수정하고 싶다면 어떻게 해야할까?
Solution with Abstract Class
위와 같은 경우 abstract method를 사용해봅시다.
abstract class Common {
void method(...){ // frozen part(fixed behavior)
// template method
/* <common code segment 1> */
contextSpecificCode(); //a hook
/* <common code segment 2> */
}
abstract void contextSpecificCode() ; // Changing part(changeable behavior)
// abstract method에 대한 구현이 없습니다.
}
class ContextA extends Common {
void contextSpecificCode() {
/* <context specific code A> */
}
}
class ContextB extends Common {
void contextSpecificCode() {
/* <context specific code B> */
}
}
상황에 맞는 코드를 placeholder로 refactoring하여 각 하위 class에서 재정의 및 사용자 지정할 수 있습니다.