상속의 문제점
상속 관계는 is-a관계이다.
- 불필요한 인터페이스 상속 문제
- 메서드 오버라이딩의 오작용 문제
- 부모 클래스와 자식 클래스의 동시 수정 문제
-> 상속은 부모 클래스와 자식 클래스의 결합도를 높인다.
상속의 대안 : 합성
합성 관계는 has-a관계이다.
상속으로 인한 조합의 폭발적인 증가
ex) 기본정책과 부가정책 조합하기
상속으로 구현하게 되면 새로운 정책을 추가하기 어려워진다. 새로운 정책을 추가하기 위해서는 불필요한 많은 클래스를 상속 계층 안에 추가해야 한다.
상속의 남용으로 하나의 기능을 추가하기 위해 필요 이상으로 많은 수의 클래스를 추가해야 하는 경우를 클래스 폭발 문제라고 하낟.
클래스 폭발 문제는 자식 클래스가 부모 클래스의 구현에 강하게 결합되도록 강요하는 상속의 근본적인 한계 때문에 발생하는 문제이다.
컴파일 시점에 자식 클래스와 부모 클래스의 관계가 정적으로 정해지기 때문에 새로운 조합이 필요한 상황에서 유일한 해결 방법은 조합의 수만큼 새로운 클래스를 추가하는 것뿐이다.
합성 관계로 변경하기
합성은 컴파일타임 관계를 런타임 관계로 변경함으로써 상속의 문제를 해결한다.
(물론 컴파일타임 의존성보다 런타임 의존성이 설계의 복잡도가 상승하기 때문에 이해하기 어려워진다.)
public class Phone {
private RatePolicy ratePolicy;
private List<Call> calls = new ArrayList<>();
public Phone(RatePolicy ratePolicy) {
this.ratePolicy = ratePolicy;
}
public List<Call> getCalls() {
return Collections.unmodifiableList(calls);
}
public Money calculateFee() {
return ratePolicy.calculate(this);
}
}
RatePolicy는 인터페이스로 요금 정책을 다양하게 주입할 수 있다. 일반 요금제의 규칙에 따라 요금을 계산하고 싶으면 Phone과 BasicRatePolicy 인스턴스를 합성하면 된다.
Phone phone = new Phone(new RegularPolicy(Money.wons(10), Duration.ofSeconds(10)));
객체 합성이 클래스 상속보다 더 좋은 방법이다. 코드를 재사용하면서 건전한 결합도를 유지할 수 있는 더 좋은 방법은 합성을 이용하는 것이다.
상속을 사용할 때는 구현 상속을 피하고 인터페이스 상속을 사용해야 한다.
'스터디' 카테고리의 다른 글
[오브젝트] 9장 유연한 설계 (0) | 2023.09.09 |
---|---|
[모던 자바 인 액션] 13장 디폴트 메서드 (0) | 2023.08.25 |
[오브젝트] 5장. 책임 할당하기 (0) | 2023.08.12 |
[모던 자바 인 액션] 10장. 도메인 전용 언어 (0) | 2023.08.12 |
[오브젝트] 04_설계 품질과 트레이드오프 (0) | 2023.08.05 |
댓글