Java/EffectiveJava

Effective Java Item18. 상속보다는 컴포지션을 사용하라.

Flambee 2025. 1. 15. 23:56

상속은 코드를 재사용하는 강력한 수단이다. 하지만 잘못 사용하면 오류를 내기 쉬운 소프트웨어를 만들게 한다.

메서드 상속과 달리 상속은 캡슐화를 깨트린다. 
- 상위 클래스가 어떻게 구현되느냐에 따라 하위 클래스의 동작에 이상이 생길 수 있다. 
- 상위 클래스는 릴리스마다 내부 구현이 달라질 수 있으며, 그 여파로 코드 한 줄 건드리지 않은 하위 클래스가 오동작할 수 있다.

상속의 단점을 피하기 위해 새로운 메서드를 통해 재정의하는 것은 상위 클래스의 메서드가 요구하는 규약을 만족하지 못할 가능성이 크다.

위 문제점을 해결하기 위해서는 새로운 클래스를 만들고 private 필드로 기존 클래스의 인스턴스를 참조하게 하는 컴포지션(composition)을 사용하자.

컴포지션을 사용하면, 기존 클래스의 내부 구현 방식의 영향에서 벗어나며, 기존 클래스에 새로운 메서드가 추가되더라도 전혀 영향받지 않는다.
- 컴포지션은 기존 클래스의 대응하는 메서드를 호출해 그 결과를 반환한다. 이 방식을 전달이라 하며, 새 클래스의 메서드들은 전달 메서드라 부른다.

컴포지션은 래퍼 클래스로 만들어 사용할 수 있으며, 래퍼 클래스를 사용한다는 것은 데코레이터 패턴을 사용한다는 것이다.

컴포지션과 전달의 조합은 넓은 의미로 위임이라고 부른다. (위임 : 래퍼 객체가 내부 객체에 자기 자신의 참조를 넘기는 경우)

상속과 컴포지션을 사용해야하는 경우
- 상속 : 하위 클래스가 상위 클래스의 진짜 하위 타입인 상황일 때 쓸 수 있는 방법 (is-a)
- 컴포지션 : 상속을 사용하는 경우가 아닐 때 사용할 수 있는 구현 방법 중 하나