공부기록/객체지향

오브젝트 11장 - 합성과 유연한 설계

DGL 2022. 1. 20. 15:15

합성을 이용하면 포함된 객체의 내부 구현이 변경되더라도 영향을 최소화할 수 있기 때문에 변경에 더 안정적인 코드를 얻을 수 있게 된다.

코드 작성 시점에 결정한 상속 관계는 변경이 불가능하지만 합성 관계는 실행 시점에 동적으로 변경할 수 있기 때문이다.

클래스 상속 - 화이트박스 재사용(상태를 알아야 하므로)

합성 - 블랙 박스 재사용(인터페이스를 통해서만 재사용)

상속을 합성으로 변경하기

불필요한 인터페이스 상속 문제 → 불필요한 인터페이스를 사용안해도 된다.

메서드 오버라이딩의 오작용 문제 → 포워딩을 사용하여 기존 인터페이스를 그대로 제공하면서, 구현에 결합없이 사용할 수 있다.

부모 클래스와 자식 클래스의 동시 수정문제 →합성으로 변경해도 해결되지는 않는다. 파급 효과를 캡슐화하여 그래도 더 낫다.

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

작은 기능들을 조합해서 더 큰 기능을 수행하는 객체를 만들어야 하는 경우, 상속의 문제점

  • 하나의 기능을 추가하거나 수정하기 위해 불필요하게 많은 수의 클래스를 추가하거나 수정해야 한다.
  • 단일 상속만 지원하는 언어에서는 상속으로 인해 오히려 중복 코드의 양이 늘어날 수 있다.

⇒ 작은 기능들을 상속받아 큰 기능을 만드는 경우, 엄청나게 많은 경우의 수를 생각해야할 수 있다.

나중에 기능을 추가하거나 수정하게 될때, 엄청 머리아플 수 있다. 또한, 오히려 코드의 중복으로 넘쳐나서, 기능 하나를 수정할 때, 오버헤드가 많아진다.

오버라이딩할 의도로 메서드를 추가했지만, 기본 구현을 제공하는 메서드를 훅 메서드라고 부른다.

합성 관계로 변경하기

합성은 컴파일타임 관계를 런타임 관계로 변경한다. 런타임에 객체의 관계를 변경할 수 있다.

작은 기능들의 조합으로 큰 기능을 개발할때, 상속이 아닌 합성 관계를 사용하자.

상속이 더 단순해보일 수 있겠지만, 기능추가나 수정에 있어서 급격한 차이를 가진다.

합성의 경우 → 각각의 기능에 대하여 OCP로 하나의 클래스만 추가하면, 기능을 추가할 수 있다.

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

살펴본 상속의 모든 단점은 구현 상속에 국한된다. 인터페이스 상속 → 다형성으로 매우 좋음?? → 거기에 캡슐화가 잘되어있다? → 거기에 아마도, 인터페이스와 구현체를 다른 패키지에 두고, 인터페이스 패키지는 변경하지 않는다??

믹스인

상속과 합성의 특성을 모두 가지고 있는 독특한 코드 재사용 방법.

객체를 생성할 때 코드 일부를 클래스 안에 섞어 넣어 재사용하는 기법.

상속의 진정한 목적은 자식 클래스를 부모 클래스와 동일한 개념적인 범주로 묶어 is-a 관계를 만들기 위한 것이다. 반면 믹스인은 말 그대로 코드를 다른 코드 안에 섞어 넣기 위한 방법이다.

합성처럼 유연하면서도 상속처럼 쉽게 코드를 재사용할 수 있는 방법이다. 어떤 언어는 믹스인을 위한 구성 요소를 언어 차원에서 직접 지원하는 데 비해 어떤 언어는 다른 용도로 고안된 요소를 이용해 믹스인을 구현하기도 한다.

믹스인은 제약을 둘 뿐 어떤 코드에 믹스인 될 것인지를 결정하지 않는다.

아하 믹스인이라는 것은... 아래의 함수들에 적용한다는 것인가? 아니면 코틀린의 해당 함수에서 사용할 수 있는 글로벌 함수(외부에서 정의할 수있는 상속기능..)와 같은 기능을 추가로 제공해준다는 것인가?

객체 선언시 with로 수정사항을 입력해줄 수 있음... 코틀린에서 봤던 기능으로 보인다.

믹스인을 추상 서브클래스라고 부르기도 한다.