10. 상속과 코드 재사용
- 객체지향 프로그래밍의 장점 중 하나는 코드를 재사용하기가 용이하다는 것입니다.
- 아래에서는 상속, 합성에 대해서 이야기를 합니다.
#
01. 상속과 중복 코드- 중복 코드는 사람들의 마음속에 의심과 불신의 씨앗을 뿌립니다.
#
DRY 원칙- 중복 코드가 가지는 가장 큰 문제는 코드를 수정하는 데 필요한 노력을 몇 배로 증가시키는 것입니다.
- 중복 코드를 판단하는 기준은 변경입니다.
- DRY는 Don't Repeat Yourself, 반복하지 마라의 의미를 가집니다.
- DRY 원칙은 한 번, 단 한번(Once and Only Once) 원칙 또는 단일 지점 제어(Single-Point Control) 원칙이라고 부릅니다.
#
중복과 변경- 기회가 생길 때마다 코드를 DRY하게 만들기 위해 노력해야 합니다.
#
상속을 이용해서 중복 코드 제거하기- 상속의 기본 아이디어는 이미 존재하는 클래스와 유사한 클래스가 필요하다면 코드를 복사하지 말고 상속을 이용해 코드를 재사용하는 것입니다.
- 상속은 결합도를 높이고, 상속이 초래하는 부모 클래스와 자식 클래스 사이의 강한 결합이 코드를 수정하기 어렵게 만듭니다.
#
강하게 결합된 Phone과 NightlyDiscountPhone- 상속 관계로 연결된 자식 클래스가 부모 클래스의 변경에 취약해지는 현상을 취약한 기반 클래스 문제라고 부릅니다.
상속을 위한 경고 1
- 자식 클래스의 메서드 안에서 super 참조를 이용해 부모 클래스의 메서드를 직접 호출할 경우 두 클래스는 강하게 결합됩니다. 즉, super 호출을 제거할 수 있는 방법을 찾아 결합도를 제거해야 합니다.
#
02. 취약한 기반 클래스 문제- 상속은 자식 클래스와 부코 믈래스의 결합도를 높입니다.
- 부모 클래스의 변경에 의해 자식 클래스가 영향을 받는 현상을 취약한 기반 클래스 문제(Fagile Base Class Problem, Brittle Base Class Problem) 이라 불립니다.
- 취약한 기반 클래스 문제는 캡슐화를 약화시키고 결합도를 높입니다.
#
불필요한 인터페이스 상속 문제- 자바의 초기 버전에서 상속을 잘못 사용한 대표적인 사례는
java.util.Properties
와java.util.Stack
입니다.
상속을 위한 경고 2
- 상속받은 부모 클래스의 메서드가 자식 클래스의 내부 구조에 대한 규칙을 깨트릴 수 있습니다.
#
메서드 오버라이딩의 오작용 문제상속을 위한 경고 3
- 자식 클래스가 부모 클래스의 메서드를 오버라이딩할 경우 부모 클래스가 자신의 메서드를 사용하는 방법에 자식 클래스가 결합할 수 있습니다.
- 상속은 코드 재사용을 위해 캡슐화를 희생합니다.
#
부모 클래스와 자식 클래스의 동시 수정 문제- 결합도는 다른 대상에 대해 알고 있는 지식의 양입니다.
상속을 위한 경고 4
- 클래스를 상속하면 결합도로 인해 자식 클래스와 부모 클래스의 구현을 영원히 변경하지 않거나, 자식 클래스와 부모 클래스를 동시에 변경하거나 둘 중 하나를 선택할 수밖에 없습니다.
#
03. Phone 다시 살펴보기#
추상화에 의존하자- 결하도를 해결하는 가장 일반적인 방법은 자식 클래스가 부모 클래스의 구현이 아닌 추상화에 의존하도록 만드는 것입니다.
- 코드 중복을 제거하기 위해 상속을 도입할 때 따르는 두 가지 원칙이 있습니다.
- 두 메서드가 유사하게 보인다면 차이점을 메서드로 추출합니다. 메서드 추출을 통해 두 메서드를 동일한 형태로 보이도록 만들 수 있습니다.
- 부모 클래스의 코드를 하위로 내리지 말고 자식 클래스의 코드를 상위로 올립니다.
#
차이를 메서드로 추출하라- 가장 먼저 할 일은 중복 코드 안에서 차이점을 별도의 메서드로 추출하는 것입니다.
#
중복 코드를 부모 클래스로 올려라- 부모 클래스를 추갛ㅏ고, 추상 클래스로 구현합니다.
#
추상화가 핵심이다- 공통 코드릴 이동시킨 후에 각 클래스는 서로 다른 변경의 이유를 가집니다.
- 클래스들은 단일 책임 원칙을 준수하기 때문에 응집도가 높습니다.
- 새로운 정보를 추가하기도 쉽습니다.
#
의도를 드러내는 이름 선택하기- 좋은 상속 계층을 구성하기 위해서는 상속 계층 안에 속한 클래스들이 구현이 아닌 추상화에 의존해야 한다는 사실을 잘 보여줍니다.
#
세금 추가하기- 클래스라는 도구는 메서드뿐만 아니라 인스턴스 변수도 함께 포함합니다.
- 인스턴스 변수의 목록이 변하지 않는 상황에서 객체의 행동만 변경된다면 상속 계층에 속한 각 클래스들을 독립적으로 진화시킬 수 있습니다.
- 상쏙은 어떤 방식으로든 부모 클래스와 자식 클래스를 결합시킵니다. 메서드 구현에 대한 결합은 추상 케서드를 추가함으로써 어느 정도 완화할 수 있지만 인스턴스 변수에 대한 잠재적인 결합을 제거할 수 있는 방법은 없습니다.
#
04. 차이에 의한 프로그래밍- 상속이 강력한 이유는 익숙한 개념을 이용해서 새로운 개념을 쉽고 빠르게 추가할 수 있습니다.
- 기존 코드와 다른 부분만을 추가함으로써 애플리케이션의 기능을 확장하는 방법을 차이에 의한 프로그래밍(programming by difference) 라고 부릅니다.
- 차이에 의한 프로그래밍의 목표는 중복 코드를 제거하고 코드를 재사용하는 것입니다.
- 코드를 재사용하면 코드의 품질은 유지하면서도 코드를 작성하는 노력과 테스트를 줄일 수 있습니다.
- 상속은 코드 재사용과 관련된 대부분의 경우에 우아한 해결 방법이 아닙니다.