도니의 iOS 프로그래밍 세상

[오브젝트] 9장 - 유연한 설계 본문

OOP

[오브젝트] 9장 - 유연한 설계

Donee 2024. 9. 28. 15:40

유연하게 대응할 수 있는 설계를 만드는 원칙 중 하나인 OCP(Open-Closed Principle)에 대해 알아보자.

Chap01. OCP

  • 소프트웨어 개체(클래스, 모듈, 함수)는 확장에 열려 있고, 수정에 닫혀 있어야 한다.
    • 확장에 대해 열려있다: 애플리케이션 요구 사항 변경시, 변경에 맞게 새로운 동작을 추가해서 기능을 확장할 수 있다.
    • 수정에 닫혀 있다: 기존 “코드”를 수정하지 않고, 애플리케이션 동작을 추가하거나 변경할 수 있다.
  • 이는 결국 추상화를 의미한다. 추상화 과정을 거쳐 문맥이 바뀌더라도 변하지 않는 부분만 남고, 변하는 부분은 생략된다.
  • 런타임 때 의존성이 변경되도록 구현하면 된다.
  • 결국, 문맥이 바뀌더라도 변하지 않는 부분을 추상화하고, 변하는 부분이 수정할 수 있도록 하는 것이 핵심
    • ex. 공통적인 로직은 변경하지 않으며, 새로운 기능이 추가될 때마다 구체 클래스가 하나씩 생성된다.(OTT를 예시로 들자면, 영화의 하나의 장르가 추가되는 것이다. 액션 장르가 추가된다고 해서, 로맨스 장르등이 영향을 받지 않는다.)

Chap02. 생성 사용 분리

  • OCP를 위해 객체는 추상화된 객체를 의존한다(ex. OTT 객체는 MovieGenre라는 interface에 의존한다)
  • OTT객체는 직접적으로 ActionGenre를 의존하지 않으며, 특정 객체를 위한 코드를 넣어선 안된다
    • 잘못된 예시
    class OTT { 
    
         init(movie: Movie) {
             if move.genre == .action {
                 self.genre = Action()
             }    
         }
         
         private let genre: MovieGenre
         
    }     
    
  • OTT에선 추상화 객체인 MoiveGenre 의 사용을 담당하고, 객체의 생성은 다른곳에서 담당해야 한다.

Factory

  • 위와 같이 생성의 책임을 OTT 가 가져선 안되지만, OTT 를 사용하는 상위 객체는 의존이 가능하다
  • 따라서, OTT 를 사용하는 상위 객체은 Netflix 라는 객체가 생성을 해서 주입해도 무방하다.
  • 하지만, Netflix 객체가 해당 객체의 생성을 담당하기 보단, 이를 위임할 객체인 Factory 를 통해 해결한다.

Chap03. 의존성 주입

  • 생성과 사용을 분리할 때, OTT에 MovieGenre 객체를 생성해서 주입해야 한다.
  • 이처럼 외부 독립 객체가 인스턴스를 생성 후 전달해서 의존성을 해결하는걸 의존성 주입(Dependency Injection)이라 한다.
  • 3가지 의존성 주입 방식
    • 생성자 주입: 객체 생성 시점에 주입
    • setter 주입: 객체 생성 후 setter 메서드를 통해 주입
    • 메서드 주입: 메서드 실행시 객체 주입

Chap04. 의존성 역전 원칙

추상화와 의존성 역전

  • 만일, OTT 객체가 Action Genre 라는 구체 타입에 의존시, 결합도가 높아지고 재사용성 및 유연성이 저해
  • 하위 추상화 레벨인 Action Gnere 를 의존으로, 상위객체가 → 하위객체의 영향을 받는 구조
  • 따라서, 의존성 역전 원칙(DIP)를 통해 추상화에 의존하도록 한다
  • 상위 수준 → 하위 수준이 아닌, 하위 수준 → 상위 수준을 의존하는 구조여야 한다.

Chap05. 유연성에 대한 조언

유연한 설계

  • 유연하고 재사용 가능한 설계가 항상 옳지 않음
  • 해당 설계의 또다른 의미는 복잡한 설계임
  • 따라서 불필요한 유연성을 통해 복잡함을 증대시키지 말고 필요할 때 변경해야 함

협력과 책임이 중요

  • 설계에 핵심은 결국 역할, 책임, 역할을 규정하는 것
  • 잘못된 설계는 역할과 책임을 규정하기 전 객체 생성등 필요하지 않는것에 집중하게 됨
    • 대표적인 케이스인 Singleton

3줄 결론

  1. 유연할 설계를 위해 OCP 구조를 적용하는 게 유리
  2. 추상화에 최대한 의존해야 하며, 의존성이 잘못될 경우 결합도 증가 및 유연성 감소등 side effect
  3. 유연한 설계가 반드시 정답이 아니기에, 필요에 따라 적용해야 함.
Comments