- 합성
새로운 클래스의 인스턴스 안에 기존 클래스의 인스턴스를 포함시키는 방법
01 상속과 중복 코드
DRY 원칙
- 중복 코드는 변경을 방해한다.
- 일단 중복 코드의 묶음을 찾았다면 찾아낸 모든 코드를 일관되게 수정해야 한다.
- 중복 여부를 판단하는 기준은 변경이다.
- DRY(Don't Repeat Yourself) 원칙
중복과 변경
중복 코드 살펴보기
중복 코드 수정하기
타입 코드 사용하기
타입 코드를 사용하면 클래스는 낮은 응집도와 높은 결하도라는 문제에 시달리게 된다.
상속을 이용해서 중복 코드 제거하기
- 상속을 염두에 두고 설계되지 않은 클래스를 상속을 이용해 재사용하는 것은 어렵다.
- 상속을 이용해 코드를 재사용하기 위해서는 부모 클래스의 개발자가 세웠던 가정이나 추론 과정을 정확하게 이해해야 한다.
강하게 결합된 Phone과 NightlyDiscountPhone
- super 참조를 이용해 부모 클래스의 메서드를 직접 호출할 경우 두 클래스는 강하게 결합된다.
02 취약한 기반 클래스 문제
- 취약한 기반 클래스 문제
- 부모 클래스의 변경에 의해 자식 클래스가 영향을 받는 현상
- 객체지향 프로그래밍의 근본적인 취약성
- 핵심적인 기반 클래스에 대한 다순한 변경이 전체 프로그램을 불안정한 상태로 만들어버릴 수도 있다.
- 상속은 자식 클래스가 부모 클래스의 구현 세부사항에 의존하도록 만들기 때문에 캡슐화를 약화
- 상속은 코드의 재사용을 위해 캡슐화의 장점을 희석시키고 구현에 대한 결합도를 높임으로써 객체지향이 가진 강력함을 반감시킨다.
불필요한 인터페이스 상속 문제
- 인터페이스 설계는 제대로 쓰기엔 쉽게, 엉터리로 사용하기엔 어렵게 만들어야 한다.
- 상속받은 부모 클래스의 메서드가 자식 클래스의 내부 구조에 대한 규칙을 깨트릴 수 있다.
메서드 오버라이딩의 오작용 문제
- 자식 클래스가 부모 클래스의 메서드를 오버라이딩할 경우 부모 클래스가 자신의 메서드를 사용하는 방법에 자식 클래스가 결합될 수 있다.
- 상속은 코드 재사용을 위해 캡슐화를 희생한다.
부모 클래스와 자식 크래스의 동시 수정 문제
- 상속은 기본적으로 부모 크래스의 구현을 재사용한다는 기본 전제를 따르기 때문에 자식 클래스가 부모 클래스의 내부에 대해 속속드링 알도록 강요한다.
- 클래스를 상속하면 결합도로 인해 자식 클래스와 부모 클래스의 구현을 영원히 변경하지 않거나, 자식 클래스와 부모 클래스를 동시에 변경하거나 둘 중 하나를 선택할 수밖에 없다.
03 Phone 다시 살펴보기
취약한 기반 클래스 문제의 영향을 최소화할 수 있는 방법은 추상화이다.
추상화에 의존하자
- 자식 클래스가 부모 크래스의 구현이 아닌 추상화에 의존하도록 만드는 것
- 차이점을 메서드로 추출한다.
- 부모 클래스의 코드를 하위로 내리지 말고 자식 클래스의 코드를 상위로 올려라
- (템플릿 메서드 패턴을 생각하면 될듯 하다)
차이를 메서드로 추출하라
중복 코드를 부모 클래스로 올려라
추상화가 핵심이다.
- 공통 코드를 이동시킨 후에 각 클래스는 서로 다른 변경의 이유를 가진다는 것에 주목하라
- 각각 하나의 변경 이유만을 가진다.
- 단일 책임 원칙을 준수
- 의존성 역전 원칙 준수
- 상속 계층이 코드를 진화시키는데 걸림돌이 된다면 추상화를 찾아내고 상속 계층 안의 클래스들이 그 추상화에 의존하도록 코드를 리팩터링하라!
의도를 드러내는 이름 선택하기
- 클래스 사이의 상속은 자식 클래스가 부모 크래스가 구현하는 행동뿐만 아니라 인스턴스 변수에 대해서도 결합하게 된다
- 인스턴스 변수에 대한 잠재적인 결합을 제거할 수 있는 방법은 없다.
04 차이에 의한 프로그래밍
- 기존 코드와 다른 부분만을 추가함으로써 애플리케이션의 기능을 확장하는 방법