리팩터링 2판
리팩터링 2판을 읽고 인상 깊었던 점과 기억에 남는 리팩토링 기법들을 소개하며, 테스트 코드의 중요성과 성능에 대한 견해, 그리고 Delegate 활용에 대한 생각을 공유합니다.

* 배경
리팩토링 2판이 나왔다는 소식을 듣고, 이번에는 진짜 읽어봐야겠다는 생각이 들어서 읽게 되었다. 코드 단위로 의미를 곱씹으며 읽으려 하다 보니, 생각보다 많은 시간이 소요되었다. "리팩토링 같이읽기" 등과 같은 스터디도 많이 진행되었는데, 스터디원과 함께 책을 정독하는 것도 좋은 방법인 것 같다. (혼자서 책을 읽다 보니, 어떤 부분은 설렁설렁 읽기도 하고, 어떤 부분은 완벽히 이해하지 못하고 넘긴 부분도 있다.)
 
* 책의 구성
앞부분(책의 20% 정도 분량)에서는 각종 리팩토링 기법들에 대한 설명, 그리고 이에 대한 마틴 파울러의 견해들을 읽을 수 있다. 이후 뒷부분에서는 앞에서 설명한 리팩토링 기법에 대한 구체적인 원칙들 + 코드 예시들이 정리되어 있다. 코드 예시는 95% Javascript 로 되어있다. 나머지 부분들은 Java 의 예시들로 구성되어 있다. 
* 인상깊었던 부분들
첫 번째로 인상깊었던 점은, "한 부분을 고칠 때마다 테스트한다" 라는 구절이 반복되는 점이었다. 그리고,  현재 회사에서 사용하고 있는 프로젝트에는 테스트 코드가 부족한 상태이다. TDD, eXtreme Programming 을 통해서 테스트 코드의 중요성은 계속 강조되고 잇지만, 1. 현재 소스코드가 불안정한 상태이고, 기획이 자주 바뀔 수 있다. 2. 테스트 코드를 작성하기에는 프로젝트 기간이 너무 촉박하다.~~(변명인 것 같다 ㅋ)~~ 등의 이유로, 테스트 코드의 작성은 항상 후순위로 밀렸었다. 하지만 마틴 파울러는 테스트 코드의 중요성을 계속 강조하였고, 리팩토링 기법에서도 테스트 과정은 항상 포함되었다. 올바른 테스트 코드의 작성에 대해서도 공부해봐야 할 것 같다.
 두 번째로 인상깊었던 부분은, 리팩토링과 성능에 대한 마틴 파울러의 견해이다. 같은 기능을 구현할 때, 대부분의 경우에는 리팩토링한 코드의 경우가 성능상으로는 뒤떨어진다. (성능과 아름다운 코드의 Trade-Off 라고 생각한다.) 때때로는 이러한 이유들로 코드 리뷰에서 구조화된 코드에 반대하는 사람들이 있는데, 이에 대해 명확히 반박하진 못하고 있었다. 마틴 파울러는 이에 대해 꽤나 명료한 근거를 제시해 준다. 그는 "리팩토링의 결과로 성능상으로 안좋아 질 수 있지만, 대부분의 경우에는 리팩토링한 코드는 성능 개선하기 더 쉬운 코드로 변한다." 라고 주장한다. 이 문장에 대해 많은 부분 설득되었다. 만약 리팩토링 한 결과로, 문제가 될 정도로 성능이 저하된 경우에는, 성능이 개선된 코드로 또다시 리팩토링하기 쉬워진다. 또한 대부분의 현대의 서버/클라이언트는 많은 경우 하드웨어가 좋은 성능을 지니고 있다.
* 기억에 남는 리팩토링
10.4 조건부 로직을 다형성으로 바꾸기 (Replace Conditional with Polymorphism)
우리가 쓰는 코드 중 생각을 가장 많이 하게 하는 부분은 바로 분기문이다. 분기문이 중첩될수록, 우리가 생각해야 할 경우의 수는 기하급수의 형태로 늘어나게 된다. (2중 if 문이면, 2의 제곱 수만큼의 경우의 수를 생각해야 한다.) 따라서 필연적으로 if 문은(switch 도 마찬가지이다.) 사용할 때마다 가독성을 생각하게 되는데, 이를 구조화하면 이러한 걱정 자체가 사라지게 되어서 인상깊었다.
// Before 
switch(bird.type) {
    case "유럽 제비": 
        return "보통이다";
    case "아프리카 제비":
        return (bird.numberOfCoconuts > 2) ? "지쳤다" : "보통이다";
    case "노르웨이 파랑 앵무":
        return (bird.voltage > 100) ? "그을렸다" : "예쁘다";
    default: 
        return "알 수 없다";
}
// After
class EuropeanSwallow {
    get plumage() {
        return "보통이다";
    }
}
...
class AfricanSwallow {
    get plumage() {
        return (this.numberOfCoconuts > 2) ? "지쳤다" : "보통이다";    
    }
}
...
class NorwegianBlueParrot {
    get plumage() {
        return (this.voltage > 100) ? "그을렸다" : "예쁘다";
    }
}
12.10 서브클래스를 위임으로 바꾸기 (Replace Subclass with Delegate)
가장 기억에 남는 리팩토링으로는, 마지막 장에 나오는 위임(Delegate) 의 사용이다. 그동안 오픈소스에 올라와있는 소스코드들을 보며, Delegate 가 정확히 무엇일까 ? 라는 의문을 품고 잇었지만, 깊게 알아보진 않았다. 책 후반부에 나오는 예시들을 보면서 Delegate 의 필요성 및 활용 방법을 깨닫게 되었다. 활용할 수 있는 상황이 발견되면, 바로 활용해 보고 싶다.
// Before 
class Order {
    get daysToShip() {
        return this._warehouse.daysToShip;
    }
}
class PriorityOrder extends Order {
    get daysToShip() {
        return this._priorityPlan.daysToShip;
    }
}
// After
class Order {
    get daysToShip() {
        return (this._priorityDelegate) 
            ? this._priorityDelegate.daysToShip 
            : this._warehouse.daysToShip;
    }
}
class PriorityOrderDelegate {
    get daysToShip() {
        return this._priorityPlan.daysToShip;
    }
}
            
            이것도 읽어보세요