본문 바로가기

책/Object

합성과 유연한 설계

상속(is-a 관계)

부모 클래스와 자식 클래스 사이의 의존성은 컴파일타임에 결정

부모 클래스의 코드를 재사용

클래스 사이의 높은 결합도


합성(has-a 관계)

두 객체 사이의 의존성은 런타임에 결정

객체의 퍼블릭 인터페이스에 의존

객체 사이의 낮은 결합도


상속을 남용했을 때 직면할 수 있는 세가지 문제

불필요한 인터페이스 상속 문제 : 자식 클래스에게 부적합한 부모 클래스의 오퍼레이션이 상속되므로 자식 클래스의 인스턴스의 상태가 불안정해짐

메서드 오버라이딩의 오작용 문제 : 자식 클래스가 부모 클래스의 메서드를 오버라이딩할 때 자식 클래스가 부모 클래스의 메서드 호출 방법에 영향을 받음

부모 클래스와 자식 클래스의 동시 수정 문제 : 부모 클래스와 자식 클래스 사이의 개념적인 결합으로 인해 부모 클래스를 변경할 때 자식 클래스도 함께 변경해야 함


상속을 합성으로 변경하기

자식 클래스에 선언된 상속 관계를 제거하고 부모 클래스의 인스턴스를 자식 클래스의 인스턴스 변수로 선언


상속으로 인한 조합의 폭발적인 증가

상속으로 인해 결합도가 높아지면 코드를 수정하는 데 필요한 작업의 양이 과도하게 늘어나는 경향이 있음

 - 하나의 기능을 추가하거나 수정하기 위해 불필요하게 많은 수의 클래스를 추가하거나 수정해야 한다

 - 단일 상속만 지원하는 언어에서는 상속으로 인해 오히려 중복 코드의 양이 늘어날 수 있다

OCP를 만족하는 설계를 만들 수 있는 한가지 방법은 부모 클래스에 새로운 추상 메서드를 추가하고 부모 클래스의 다른 메서드 안에서 호출하는 것

 - 추상 메서드의 단점은 상속 계층에 속하는 모든 자식 클래스가 추상 메서드를 오버라이딩해야 한다는 것

 - 훅 메서추상 메서드와 동일하게 자식 클래스에서 오버라이딩할 의도로 메서드를 추가했지만 편의를 위해 기본 구현을 제공하는 메서드

클래스 폭발 문제 또는 조합의 폭발 문제상속의 남용으로 하나의 기능을 추가하기 위해 필요 이상으로 많은 수의 클래스를 추가해야 하는 경우


합성 관계로 변경하기

구현이 아닌 퍼블릭 인터페이스에 대해서만 의존할 수 있기 때문에 런타임에 객체의 관계를 변경할 수 있음

 - 상속은 조합의 결과를 개별 클래스 안으로 밀어 넣는 방법

 - 합성은 조합을 구성하는 요소들을 개별 클래스로 구현한 후 실행 시점에 인스턴스를 조립하는 방법을 사용하는 것

컴파일타임 의존성과 런타임 의존성의 거리가 멀어질수록 설계의 복잡도가 상승해서 코드를 이해하기는 어려워짐(적절한 트레이드오프가 있어야함)


믹스인

객체를 생성할 때 코드 일부를 클래스 안에 섞어 넣어 재사용하는 기법

 - 컴파일 시점에 필요한 코드 조각을 조합하는 재사용 방법


' > Object' 카테고리의 다른 글

서브클래싱과 서브타이핑  (0) 2020.08.25
다형성  (0) 2020.08.10
상속과 코드 재사용  (0) 2020.07.27
유연한 설계  (0) 2020.07.13
의존성 관리하기  (0) 2020.07.06