////
Search

11장 - 합성과 유연한 설계

Date
2024/03/25 04:00
Tags

1. 개요

상속과 합성은 객체지향 프로그래밍에서 가장 널리 사용되는 코드 재사용 기법이다.
상속 = 부모 클래스와 자식 클래스를 연결해 코드를 재사용
합성 = 전체를 표현하는 객체가 부분을 표현하는 객체를 포함해 코드를 재사용
상속과 합성은 재사용의 대상이 다르다.
상속은 부모 클래스 안에 구현된 코드 자체를 재사용
합성은 포함되는 객체의 퍼블릭 인터페이스를 재사용한다.

2. 상속을 합성으로 변경하기

상속을 남용했을 경우 마주할 수 있는 문제는 크게 3가지다.

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

자식 클래스에게는 부적합한 부모 클래스의 오퍼레이션이 상속되기 때문에 자식 클래스 인스턴스의 상태가 불안정해지는 문제
클래스의 상속관계를 제거하고 상속 하고자 하는 부모 클래스를 자식 클래스의 인스턴스 변수로 포함시켜 해결한다.

2.2. 메서드 오버라이딩의 오작용 문제

자식 클래스가 부모 클래스의 메서드를 오버라이딩할 때 자식 클래스가 부모 클래스의 메서드 호출 방법에 영향을 받는 문제
메서드 오버라이딩이 아닌 인스턴스 변수에 포함시켜 퍼블릭 인터페이스를 통해서 기능을 확장시킨다.

2.3. 부모 클래스와 자식 클래스의 동시 수정 문제

부모 클래스와 자식 클래스 사이의 개념적인 결합으로 인해 부모 클래스를 변경할 때 자식 클래스도 함께 변경해야 하는 문제
public class PersonaIPIay1ist { private Playlist playlist = new Playlist(); public void append(song song) { playlist.append(song); } public void remove(Song song) { playlist.getTracks() .remove(song); playlist.getSingers().remove(song.getSinger()); } }
Java
복사
해당 클래스는 상속이 아는 합성이지만, 여전히 기능 변경 시 함께 수정되어야한다.
그렇다고 하더라도 파급효과를 줄이기 위해 합성을 쓰는편이 더 좋다.

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

상속으로 인해 결합도가 높아지면 코드 수정에 필요한 작업의 양이 과도하게 늘어나는 경향이 있다.
일반적으로 작은 기능들을 조합해 더 큰 기능을 수행하는 객체를 만들어야 하는 경우
일반적으로 발생하는 두 문제점
하나의 기능을 추가하거나 수정하기 위해 불필요하게 많은 수의 클래스를 추가하거나 수정해야 한다.
단일 상속만 지원하는 언어에서는 상속으로 인해 오히려 중복 코드의 양이 늘어날 수 있다.
이처럼 상속의 남용으로 하나의 기능을 추가하기 위해 필요 이상으로 많은 수의 클래스를 추가해야 하는 경우를 가리켜 클래스 폭발(class explosion) 문제 또는 조합의 폭발(combinational explosion) 문제라고 부른다.
컴파일 타임에 결정된 자식/부모 클래스 사이의 관계는 변경될 수 없다.
때문에 자식 클래스와 부모 클래스의 다양한 조합이 필요한 상황에서 유일한 해결 방법은 조합의 수만큼 새로운 클래스를 추가하는 것뿐이다.
해당 문제는 추가 뿐 아니라 수정에도 문제가 되는데 중복코드 수정이 누락될 경우 버그가 발생할 수 있다.

4. 합성 관계로 변경하기

상속 관계는 컴파일타임에 결정되고 고정되기 때문에 실행 도중 변경이 불가능하다.
따라서 여러 기능을 조합해야 하는 설계에 상속을 이용하면 모든 조합 가능한 경우별로 클래스를 추가해야 한다.
합성은 컴파일타임 관계를 런타임으로 변경해 이 문제를 해결한다.
합성을 사용하면 컴파일 의존성에 속박되지 않고 다양한 방식의 런타임 의존성을 구성할 수 있다.
해당 합성 구조로 인해서 새로운 정책/부가 정책 추가가 편리해진다.
코드를 재사용하면서도 건정한 결합도를 유지하는 합성이 상속보다 더 좋은 방법이다.

5. 믹스인

상속을 사용하면 다른 클래스를 간편하게 재사용하고 점진적으로 확장할 수 있지만 부모/자식 클래스가 강하게 결합되어 수정과 확장이 취약해진다.
믹스인은 객체를 생성할 때 코드 일부를 클래스 안에 섞어 넣어 재사용하는 기법을 가르키는 용어다.
합성 = 실행 시점에 객체를 조합하는 재사용 방법
믹스인 = 컴파일 시점에 필요한 코드 조각을 조합하는 재사용 방법
믹스인 ≠ 상속
방법이 무엇이건 코드를 다른 코드 안에 유연하게 섞어 넣을 수 있다면 믹스인이라 부를 수 있다.