도니의 iOS 프로그래밍 세상

[오브젝트] 11장 - 합성과 유연한 설계 본문

OOP

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

Donee 2024. 10. 9. 19:53
  • 상속과 합성은 가장 많이 사용되는 코드 재사용 기법
  • 상속은 클래스 사이에 정적인 관계, 합성은 동적인 관계
  • 상속은 부모 클래스에 구현에 의존하기 때문에 자식과 부모간의 강한 결합도를 가짐
    • (부모 클래스이 구현에 의존하지 않는다면 어떻게 될까? → 부모 inteface에 의존한 상속을 설계한다면 더욱 유연해지지 않을까?)
  • 합성은 퍼블릭 인터페이스에 의존하기 때문에 객체 내부 구현 변경에 따른 영향이 최소화되어 안정적임

→ 이로인해, 합성이 상속에 비해 유연한 설계가 가능함(구현이 아닌, 인터페이스에 의존하기 때문)

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

  • 상속이 가진 부모 자식간의 결합도는 코드 수정간 더 많은 작업량을 요구함
  • 합성은 상속과 같이 중복을 제거하면서도 보다 간단하게 처리가 가능함

새로운 클래스 생성

  • 기능 A, B를 구현하는 클래스 A, B가 존재할 때 C의 기능이 추가된다면?
    • 합성의 경우 A, B, C를 갖고 조합을 해서 사용이 가능함(ex, (A, B), (A,B), (A, C)와 같은 조합으로 주입하면 됨)
    • 상속의 경우 새로운 기능이 추가될 때마다 연관된 새로운 클래스들을 추가적으로 만들어야 함(ex. AB class, AC class, BC class)
    • 이를 우리는 클래스 폭발 or 조합의 폭발이라고 함
    • 자식 ↔ 클래스간의 강한 결합으로 인해, 다양한 조합을 위해 새로운 클래스를 계속 생성해줘야 하는 것
  • 상속과 합성의 가장 큰 차이는 정적, 동적인 관계
  • 컴파일 의존성과 런타임 의존성의 거리가 멀어질경우 설계가 유연해짐, 따라서 합성이 더욱 유연한 설계
  • 하지만 복잡도를 더욱 올리는 trade-off를 발생시킴

2. 믹스인

  • 객체 생성시 코드 일부를 클래스 안에 넣어 재사용하는 기법
  • 컴파일 시점에 필요한 코드를 조각하여 조합하는 재사용 방법
  • 상속과 달리 has-a관계로 코드를 다른 코드안에 넣는 기법을 의미함(상속은 is-a관계로 부모 ↔ 자식을 정의)
  • 주로 swift에서는 프로토콜을 통해 구현됨
  • protocol Flying { func fly() } protocol Swimming { func swim() } class Animal { func sound() { print("Animal sound") } } class Bird: Animal, Flying { func fly() { print("Flying in the sky") } }
  • has-a 관계이기 때문에, 클래스에 많은 기능이 들어가 SRP를 위반할 수 있음(과도한 기능 추가로 인해 클래스가 굉장히 비대한 역할을 수행할 수 있기에)

결론

  • 합성은 상속에 비해 퍼블릭 인터페이스에 의존하기 때문에 보다 유연한 설계가 가능
    • 상속또한 자식 클래스가 부모 클래스의 구현이 아닌 인터페이스에 의존한다면 더욱 유연한 설계가 되지 않을까?
  • 조합과 상속의 가장 큰 차이점은 의존성 시기(상속: 컴파일 타임, 조합: 런타임)
  • 믹스인과 같이 클래스에 추가적인 프로토콜을 통해서 기능 추가 가능, but 책임이 과도하게 커질 위험이 존재한다.
Comments