본문 바로가기
Programming/Java

[이펙티브자바] 아이템18. 상속보다는 컴포지션을 사용하라.

by 읽고 쓰는 개발자 2023. 3. 19.

아이템18. 상속보다는 컴포지션을 사용하라.

핵심정리

  • 패키지 경계를 넘어 다른 패키지의 구체 클래스를 상속하는 일은 위험하다.
    • 인터페이스 상속(implementation) 얘기가 아니라 구체적인 구현 상속에 한해서 
    • 상위 클래스에서 제공하는 메서드 구현이 바뀐다면...
    • 상위 클래스에서 새로운 메서드가 생긴다면... 
    • 예시) HashSet의 addAll 메소드
      내부 로직에서 add 메소드 호출하는 것을 알고 사용해야 함.
      -> 만약 addAll의 내부 구현이 바뀐다면 하위 클래스들의 로직도 바뀌어야 함 - 캡슐화 깨지는 것
      super.addAll 호출 시, 내부적으로 상속하여 overriding add를 호출하여 count가 두 번 집계됨
    • 상속을 받지 않고 위임한 composition에서는 sideEffect가 발생하지 않음 - 캡슐화 지켜진 것 
  • 컴포지션(Composition)
    • 새로운 클래스를 만들고 private 필드로 기존 클래스의 인스턴스를 참조
    • 새 클래스의 인스턴스 메소드들은 기존 클래스에 대응하는 메소드를 호출해 그 결과를 반환함
    • 기존 클래스의 구현이 바뀌거나, 새로운 메소드가 생기더라도 아무런 영향 받지 않음

완벽공략

  • 데코레이터(Decorator) 패턴 : 상속이 아닌 위임을 사용하는 대표적인 디자인 패턴
    • 기존 코드를 변경하지 않고 부가기능을 추가하는 패턴
    • 상속이 아닌 위임을 사용하여 보다 유연하게(런타임에) 부가 기능을 추가하는 것도 가능 
    • 단점 : 조합하는 코드가 복잡할 수 있음
    • 더 궁금하다면 기선님의 디자인패턴 강의 수강하기 
  • 컴포지션과 전달 조합은 넓은 의미로 위임(delegation)이라고 부른다.
    • 교조적으로 다른 의미를 갖지만, (컴포지션, delegation 등) 사용할 때의 차이는 없기 때문에 중요하다고 생각하지 않음
  • 콜백 프레임워크와 셀프 문제 
    • 콜백 프레임워크와 래퍼를 같이 사용했을 때 발생할 수 있는 문제 : SELF문제
    • 콜백 함수 : 다른 함수(A)의 인자로 전달된 함수(B)로, 해당 함수(A) 내부에서 필요한 시점에 호출될 수 있는 함수(B)를 말한다.
    • 래퍼로 감싸고 있는 내부 객체가 어떤 클래스(A)의 콜백으로(B) 사용되는 경우에 this를 전달한다면, 해당 클래스(A)는 래퍼가 아닌 내부 객체를 호출한다. (SELF문제)

 

출처 : 백기선님 - 이펙티브 자바 완벽 공략 2부