서적/Object

11장 합성과 유연한 설계

Mo_bi!e 2026. 3. 18. 22:52

개인 이해 정리

  • Dry 원칙 해결 방법 ->
    1. 상속(is-a) : 코드 재사용 (컴파일 타임)
    2. 합성(has-a) : 퍼블릭 인터페이스 재사용 (런 타임)
  • 두개는 코드 재사용이라는 동일한 목적을 제외하면 구현 방법부터 변경 다루는 방법까지 모든 면에서 차이가 있다.

1. 상속을 합성으로 변경하기 (상속 으로부터의 안정성 향상)

상속 문제

  • 불필요한 인터페이스 상속 문제 : 자식 클래스에게는 부적합한 부모 클래스의 오퍼레이션이 상속
  • 메서드 오버라이딩 부작용 문제 : 자식 클래스가 부모 클래스 메서드 호출방법에 영향 받는 문제
  • 부모 클래스와 자식 클래스의 동시 수정 문제 : 부모 클래스 변경 시 자식 클래스도 함께 변경하는 문제

불필요한 인터페이스 상속문제

과제 1. 상속코드를 합성으로 변경하기 : 참고

  • 합성으로 변경에 불안정한 코드를 안정적으로 유지하는 방법이 있다.

2. 상속으로 인한 조합의 폭발적인 증가 (상속의 유연성 문제점)

상속을 이용해서 기본 정책 구현하기

  • 부모클래스에 추상 메서드를 추가하면 모든 자식클래스들이 추상 메서드를 오버라이딩 해야하는 문제가 발생한다.
  • 모든 추상 메서드는 구현이 동일한 문제도 있다.
  • 중복 코드 문제를 해결하기 쉽지 않다

중복 코드의 덫에 걸리다

  • 부가 정책은 자유롭게 조합할 수있어야하고, 적용되는 순서도 임의로 결정이 필요하다
    • 상속을 이용한 해결 방법은 모든 가능한 조합별로 자식 클래스를 하나씩 추가하는 것이다.
    • 하지만 새로운 정책을 추가하기 쉽지 않다. -> 불필요하게 많은 수의 클래스를 상속 계층 안에 추가해야한다
  • 상속의 남용으로 하나의 기능을 추가하기 위해 필요 이상으로 많은 수의 클래스를 추가해야하는 경우를 가리켜 '클래스 폭발'문제 라고 부른다
    • 비단 추가할때 뿐만 아니라, 기능을 수정할 때도 문제가 된다
    • 만약 세금 정책 변경 시 모든 클래스를 찾아 동일한 방식으로 수정해야한다
    • 이 방식의 해결 방법은 상속을 포기하는 것이다

3. 합성 관계로 변경하기 (상속으로 부터 유연성 향상)

과제 2. 핸드폰 과금 시스템 '정책 조합' 마법 체험하기 (참고)

  • 합성은 컴파일 타임 관계를 런타임 관계로 변경하여 모든 조합 가능한 경우별로 클래스를 추가할 필요가 없다
    • 합성을 사용하면 퍼블릭 인터페이스에 대해서만 의존할 수 있기 때문이다.
    • 클래스 폭발 문제를 해결하기 위해 합성을 사용하는 이유는 런타임에 객체 사이에 의존성을 자유롭게 변경할 수있기 때문이다.
  • 설계는 트레이드 오프의 산물이다. 대부분의 경우 단순한 설계가 정답이지만, 변경에 따르는 고통이 크다면 유연성을 채택하는 것이 현명하다

1. 기본 정책 합성하기

  • 각 정책을 별도의 클래스로 합성하기
  • 그 결과 오직 하나의 클래스만 추가하고, 런타임에 필요한 정책들을 조합해서 원하는 기능을 얻을 수 있다.
    • 요구 사항 변경할 때 오직 하나의 클래스만 수정해도 된다

2. 객체 합성이 클래스 상속보다 더 좋은 방법이다.

  • OOP 에서 상속은 코드 재사용을 위한 우하한 해결책은 아니다. 부모와 자식 클래스 간에 강결합을 시켜 코드의 진화를 방해한다
  • 코드를 재사용 하면서도, 건전한 결합도를 유지 하는 방법은 합성이다.
  • 문제가 되는 상속은 구현 상속에 국한된다. -> 13장에서 인터페이스 상속에 대해서 살펴보자

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

10장 상속과 코드 재사용  (3) 2026.03.08
9장 유연한 설계  (6) 2026.03.04
6장 메시지와 인터페이스 / 8장 의존성 관리하기  (8) 2026.02.24
5장 책임 할당하기  (3) 2026.02.08
4장 설계품질과 트레이드 오프  (3) 2026.02.03