2장: 리팩터링 깊게 들여다보기
2.1 가독성 및 유지보수성 향상
리팩터링이란?
-> 더 나은 코드를 만드는 것
-> 코드가 하는 일을 변경하지 않는 것
2.1.1 코드 개선
- 가독성
의도를 전달하기 위한 코드의 성질
-> 가독성이 좋으면, 코드를 이해하기 쉽다.
- 유지보수성
새로운 기능 추가나 버그 해결을 위해 얼마나 많은 후보를 조사해야 하는가
불변속성
코드에서 상태를 명시적으로 확인하지 않는 속성으로, 에러가 나기 쉽다.
ex) a.props1에서 props1은 a에 반드시 존재한다
-> 변수를 명시적으로 체크하는 코드를 추가하여 불변속성을 없애야 한다!
-> 위 코드를 가능한 코드 수행 작업 근처에 배치하자!
= 1불변속성의 범위제한(localizing invariants): 함께 변하는 것은 함께 있어야 한다.
2.1.2 코드가 하는 일을 바꾸지 않고 유지보수하기
리팩토링 결과 성능이 떨어져도 괜찮은 이유
- 대부분의 시스템에서, 성능은 가독성과 유지보수성보다 가치가 떨어진다!
-
성능이 중요한 경우, 최적화는 다른 단계에서 해결해야 한다!
2.2 속도, 유연성 및 안정성 확보
2.2.1 상속보다는 컴포지션 사용
상속보다 컴포지션을 사용하라
→ 둘 다 객체 지향 프로그래밍(OOP) 디자인 패턴.
관계 형태 | 컴포지션 | 상속 |
---|---|---|
형태 | “has-a” 한 객체가 다른 객체를 포함하거나 구성하는 방식 ex) 자동차 객체가 엔진, 바퀴, 그리고 핸들과 같은 부속품 객체들을 포함하는 것 |
“is-a” 한 클래스가 다른 클래스의 특성을 상속받아 확장하거나 재사용하는 방식 ex) 자식 클래스가 부모 클래스의 모든 멤버와 메서드를 상속받는 것 |
결합도 | 낮음. 부품 객체를 변경하더라도 부모 객체에 영향을 미치지 않는다 | 높음. 자식 클래스는 부모 클래스의 구현 세부 정보에 의존한다 |
확장성 | 더 큰 유연성과 확장성을 -> 새로운 기능을 추가하려면 새로운 객체를 만들고 기존 객체에 연결하는 방식으로 확장 | 상속은 부모 클래스의 변경이 자식 클래스에 영향 -> 새로운 기능을 추가하기 위해 부모 클래스를 수정해야 할 수도 있음 |
코드 재사용 | 쉬움. 작은 부품 객체들을 여러 곳에서 조합하여 사용가능 | 덜 유연. 상속은 코드의 재사용을 지원하지만 부모 클래스와 자식 클래스 간의 강력한 결합 존재 |
interfact Bird {
hasBeak(): boolean;
canFly(): boolean;
}
class CommonBird implements Bird{
hasBeak() {return true;}
canFly() {return true;}
}
//상속
class Penguin extends CommonBird{
canFly {return false;}
}
//컴포지션
class Penguin implements Bird{
private bird=new CommonBird();
hasBeak() {return bird.hasBeak(); }
canFly() {return false;}
}
canSwim()이라는 새 메서드를 CommonBird에 추가하면..?
-> 컴포지션에서는 canSwim이 명시적으로 정의되지 않아 오류가 발생하므로, 이를 잡아낼 수 있다!
2.2.2 수정이 아니라 추가로 코드를 변경
컴포지션은 기존 코드를 변경하지 않고도 추가(addition)를 통해 변경이 가능하다!
개방-폐쇄의 원칙
소프트웨어 구성요소들은 확장에 대해 열려있어야 하고, 수정에 대해 닫혀있어야 한다.
프로그래밍 속도
주변 코드를 손상시키지 않도록, 다른 코드를 건드리지 않고 추가해야 한다.
-> 코드베이스가 계속 늘어나게 되므로 사용하지 않는 코드는 최대한 빨리 삭제해야 한다!
-> 슈퍼팟은 이것때문에 6000줄이 넘는 코드가 되었다…..
안정성
추가를 통해 기존 코드의 보존이 가능하다
-> 기존 코드의 에러 발생 방지가 가능하다
-> 불변속성의 범위 제한이 가능하다
-> 시스템의 안정성이 향상된다!
2.3 리팩터링과 일상 업무
항상 여러분이 왔을 때보다 더 좋게 만들어 놓고 떠나세요. -보이 스카우트 규칙
(클린코드에서도 언급하던 규칙!)
-> 작업 전후의 리팩토링을 통해 기술 부채를 가능한 없애야 한다.
2.3.1 학습 방법으로서의 리팩터링
더 나은 코드의 장점을 보고 경험하는 것
-> 코드를 작성하고 생각하는 방식을 바꾼다!
-> 확보된 안정성의 활용방안을 찾기 시작한다.