Composition over inheritance
상속보다는 구성을 활용한다.
Head First Design Patterns을 읽으면서 이 구문이 의미하는 바가 정확하게 와 닿지 않아서 상속과 구성이 어떤 것이며, 왜 상속보다는 구성을 활용하는것을 권장하는지 이해하고자 이 글을 작성한다.
Inheritance(상속)
Inheritance(이하 상속)은 Super Class(이하 부모 클래스)의 특징을 계승하여 Sub Class(이하 자식 클래스)를 도출해 Class 계층으로 형성하는 개체 지향 프로그래밍의 한 방법이다.
is-a관계로 표현되기도 하며, 자식 클래스는 부모 클래스가 가진 특징 이외에 새로운 추가 특징을 가질 수 있다.
예시 코드
Composition
Object composition(이하 구성)은 개체나 데이터 타입을 더 복잡(complex)한 것으로 결합하는 방법을 말한다. has-a관계로 표현되기도 하며 A Class가 B Class포함하는 경우 B Class는 A Class 없이 존재할 수 없는 경우를 말한다.
UML로 나타내면 아래 그림과 같다.
예시코드
Composition over inheritance
상속보다 구성을 선호하는 것은 설계의 유연성을 높이는 설계 원칙이다. A Class와 B Class의 공통점을 찾아서 상속관계를 만드려고 하는 것보다 다양한 구성으로 개체를 구축하면 사소한 변경에 덜 취약해 질 수 있다. 이는 미래의 요구사항을 좀더 쉽게 수용할 수있다는 점에서 큰 장점을 가진다.
상속이 가진 단점은 구성으로 설계하도록 권장하는 또 다른 이유를 가진다.
- 런타임에서 부모 클래스로부터 구현된 자식 클래스를 변경할 수 없다. (이 문제는 Decorator pattern을 통해 해결할 수 있다.)
- 부모 클래스 세부 사항에 자식 클래스를 노출하므로 캡슐화를 깨뜨리는 경우가 많이 발생한다. (많은 개발 언어에서
protected접근자를 제공함으로써 데이터 접근을 제어할 수 있다.) - 무분별한 상속의 재 사용은 코드를 이해하는데 어려움을 줄 수 있다. (이 문제는 개발자의 역량에 맡겨야 한다고 생각한다.)
물론 상속이 무조건 나쁘다는 것은 아니다. 구성 또한 아래와 같이 단점을 가지고 있다.
- 상속을 건너뛰고 구성에만 중점을 두면 상속을 사용하는 경우 상속을 사용할때 필요하지 않았던 코드들을 작성해야 하는 경우가 종종 있다.
- 가끔 자신을 반복하도록 강요되기도 하며 이는 DRY 원칙에 위배된다.
- 구성에서는 위임이 자주 필요하며, 함수는 다른 코드 없이 위임된 개체의 다른 함수를 호출한다. 상속된 함수를 호출하는 것은 상속되지 않은 함수를 호출하는 것 만큼 빠르거나 약간 느릴 수 있지만 일반적으로 두번의 연속 함수 호출보다는 빠르다.
실제 시스템의 동작방식, 상황 및 구조적인 의미에 따라 상속으로 구현하고 구성으로 구현하는 방법을 선택해야 한다. 즉, 차이점을 이해하고 알맞게 사용해야 한다.
상속보다는 구성을 활용한다.라는 말은 상속으로 구현하기 전에 구성으로 구현한는 것을 먼저 고려해보자라고 생각하면 더 좋을 것 같다.
https://stackoverflow.com/questions/2399544/difference-between-inheritance-and-composition
https://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)
https://en.wikipedia.org/wiki/Object_composition
https://en.wikipedia.org/wiki/Composition_over_inheritance
http://www.trytoprogram.com/cplusplus-programming/inheritance/
