DRY ( Don't Repeat Yourself ) 원칙
- 모든 지식은 시스템 내에서 단일하고, 애매하지 않고, 정말로 믿을 만한 표현 양식을 가져야 한다.
- DRY (Don't Repeat Yourself)는 '반복하지 마라'라는 뜻
- 중복 코드는 변경을 방해한다.
- 코드를 수정하는 데 필요한 노력을 몇배로 증가시킨다.
- 중복 여부를 판단하는 기준은 변경
- 요구사항이 변경됐을 때 두 코드를 함께 수정해야 한다면 이 코드는 중복이다.
- 한번, 단 한번( Once and Only Once ) 원칙 또는 단일 지점 제어 (Single-Point Controller ) 원칙이라고도 한다.
-
중복과 변경
- 중복코드는 새로운 중복코드를 부르고, 버그 발생 가능성도 높아진다.
- 민첩하게 변경하기 위해서는 중복 코드를 추가하는 대신 제거해야 한다.
- 중복을 제거하는 방법 중 하나는 클래스를 하나로 합쳐 타입 코드를 추가해 로직을 분기해야 한다.
- 하지만, 낮은 응집도와 높은 결합도를 갖게 된다.
상속을 이용해서 중복 코드 제거하기
- 상속을 이용해 코드를 재사용하기 위해서는 부모 클래스의 개발자가 세웠던 가정이나 추론 과정을 정확하게 이해해야 한다.
- 이것은 자식 클래스 자식 클래스의 작성자가 부모 클래스의 구현 방법에 대한 정확한 지식을 가져야 한다는 걸 의미한다.
- 그렇기에, 상속은 결합도를 높인다.
취약한 기반 클래스 문제
- 상속 관계로 연결된 자식 클래스가 부모 클래스의 변경에 취약해지는 현상을 이야기한다.
- 부모 클래스의 불필요한 세부사항에 엮이게 된다.
발생하는 문제점
- 캡슐화를 악화하고 결합도를 높인다.
- 상속은 자식 클래스가 부모 클래스의 구현 세부사항에 의존하도록 만든다.
- 객체 사용의 이유는 구현과 관련된 세부사항을 인터페이스 뒤로 캡슐화하는 것이다.
- 상속을 사용하면 부모 클래스의 퍼블릭 인터페이스가 아닌 구현을 변경하더라도 자식 클래스가 영향받기 쉬워짐
- 따라서, 상속은 코드의 재사용을 위해 캡슐화의 장점을 희석시키고 구현에 대한 결합도를 높인다.
불필요한 인터페이스 상속 문제
- 상속받은 부모 클래스의 메서드가 자식 클래스의 내부 구조에 대한 규칙을 깨트릴 수 있다.
- 자식 클래스가 부모 클래스의 메서드를 오버 라이딩할 경우, 부모 클래스가 자신의 메서드를 사용하는 방법에 자식 클래스가 결합될 수 있다.
- 설계는 트레이드오프 활동이라는 사실을 기억해야 한다. 상속은 코드 재사용을 위해 캡슐화를 희생한다. 완벽한 캡슐화를 원한다면 코드 재사용을 포기하거나 상속 외 다른 방법을 사용해야 한다.
부모 클래스와 자식 클래스의 동시 수정 문제
- 상속을 사용하면 자식 클래스가 부모 클래스의 구현에 강하게 결합되기 때문에, 불필요한 인터페이스를 상속받지 않아도 동시에 수정해야 할 수 있다.
- 상속은 기본적으로 부모 클래스의 구현을 재사용한다는 기본 전제를 따르기 때문에, 자식 클래스가 부모 클래스의 내부에 대해 속속들이 알도록 강요한다.
상속으로 인한 피해를 최소화할 수 있는 방법
추상화에 의존하자
- 부모 클래스와 자식 클래스 모두 추상화에 의존하도록 수정해야 한다.
- 두 메서드가 유사하게 보인다면 차이점을 메서드로 추출해야 한다. 메서드 추출을 통해 두 메서드를 동일한 형태로 보이도록 만들 수 있다.
- 부모 클래스의 코드를 하위로 내리지 말고 자식 클래스의 코드를 상위로 올려라. 재사용 성과 응집도 측면에서 더 뛰어난 결과를 얻을 수 있다.
차이를 메서드로 추출하라
- 변하는 것으로부터 변하지 않는 것을 분리해라 변하는 부분을 찾고 이를 캡슐화해라
변하는 부분을 따로 빼게 되면, 변하지 않는 부분들은 동일해지기에, 부모 클래스로 올려라
중복 코드를 부모 클래스로 올려라
- 자식 클래스들 사이의 공통점을 부모 클래스로 옮김으로써 실제 코드를 기반으로 상속 계층을 구성할 수 있다.
- 공통 코드를 옮길 때 인스턴스 변수보다 메서드를 먼저 이동하는 것이 편하다.
- 메서드를 다 옮기고 나서 필요한 인스턴스 변수나 메서드가 무엇인지 컴파일 에러를 통해 자동으로 알 수 있기 때문이다.
- 컴파일 에러를 바탕으로 부모 클래스에 꼭 필요한 코드만 이동시킬 수 있다.
추상화가 핵심이다.
- 공통 코드를 이동시킨 후 각 클래스는 서로 다른 변경의 이유를 가진다는 것에 주목하라
마치며
해당 챕터의 경우 코드를 통해 더 직관적으로 이해하는 것이 편했고 반가운 개념들 또한 많았기에 재미있게 볼 수 있었다. :)