본문 바로가기
스터디

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

by eunoo 2023. 9. 9.

이번 장에서는 유연한 설계를 위한 기법들에 대해 알아보았다.

 

01 개방 폐쇄 원칙

OCP? 확장에는 열려있고, 수정에는 닫혀있다. = 애플리케이션의 요구사항에 대해 기존 코드의 수정없이 새로운 동작을 추가하여 애플리케이션의 기능을 확장할 수 있다.

 

OCP을 지키는 법 

  • 컴파일 의존성을 고정하고, 런타임 의존성은 변경하도록 설계하기
  • 추상화에 의존하여 설계하기 = 변하지 않는 부분은 고정하고, 변하는 부분은 생략한다.

 

02 생성 사용 분리

=> 객체를 생성하고, 사용하는 코드를 분리하라.

  • Factory 사용하기 : 오로지 객체 생성의 책임만을 가지는 Factory를 생성하자. 팩토리를 통해 객체를 생성하는 코드를 분리할 수 있다.
  • 순수 가공물(Pure Fabrication)에게 책임 할당하기 : 도메인 개념을 담은 객체 높은 결합도, 낮은 응집도를 가진다면 도메인 상에는 존재하지 않는 Pure한 객체를 만들어 그 객체에게 책임을 할당한다. ex) Factory에게 객체 생성의 책임을 할당.

 

03 의존성 주입

=> 외부에서 객체를 생성하고 이를 전달해서 주입하는 방식

  • 생성자 주입 : 불변, 필수(컴파일 시점에 의존성이 주입되었는지 명확하게 파악할 수 있다.)
  • 수정자 주입 : 변경 가능, 선택 (컴파일 시점에 의존성을 확인하지 않기 때문에 의존성 주입이 누락될 수도 있다.)
  • 메서드 주입 : 주입된 의존성이 한 두개의 메서드에서만 사용된다면 메서드 인자로 전달하는 게 나을 수도 있다.

 

의존성 주입 외 의존성을 해결하는 방법 : Service Locator 패턴

  • Service Locator : 의존성을 가지고 있는 객체들을 저장하는 공간
  • A객체가 B객체를 의존하고 있을 때, B 객체를 Service Locator 에 저장하고, A 객체가 내부적으로 Service Locator에게 B 객체를 요청한다.
  • 문제점 : 의존성을 내부적으로 감춘다. A객체에서 B객체에 대한 의존성을 볼 수 없다.
    • 의존성을 숨기게 되면 의존성과 관련된 문제를 컴파일 시점에 발견할 수가 없다.
    • 단위 테스트 또한 어렵다. 단위 테스트는 고립된 상태에 이뤄져야 하는데 Service Locator를 사용하게 되면 모두 Service Locator의 상태를 공유하게 된다.
    • 의존성을 이해하기 위해 코드 내부를 봐야하므로 캡슐화를 위반한다.
    • 즉 숨겨진 의존성은 나쁘다.

 

04 의존성 역전 원칙

"추상화에 의존하라." 

  • 전통적인 방식 : 상위 수준의 모듈이 하위 수준의 모듈에 의존한다. 구체적인 것에 의존한다.
  • 전통적인 방식을 역전 : 상위 수준의 모듈과 하위 수준의 모듈 모두 추상화에 의존한다. 구체적인 것 또한 추상화에 의존한다.

패키지의 구조 역전

  • 역전은 의존성의 방향뿐만 아니라 모듈을 어떻게 구성할 건지 결정하는 방법도 뒤바꾸었다.
  • 전통적인 방식 : 인터페이스가 하위 수준 모듈에 속한다. ex) A 모듈 : Movie   B모듈 : DiscountPolicy, AmountDiscountPolicy, PercentDiscountPolicy
  • 전통적인 방식 역전 : 인터페이스가 상위 수준 모듈에 속한다. ex) A모듈 : Movie, DiscountPolicy  B모듈:AmountDiscountPolicy, PercentDiscountPolicy

 

05 유연성에 대한 조언

유연성은 항상 복잡성을 수반한다. 유연한 설계가 항상 옳은 것은 아니다. 유연한 설계는 유연성이 필요할 때만 옳다.

복잡성이 필요한 합리적인 이유를 제시해야 한다.

 

중요한 건 역할, 책임, 협력이다. 협력을 재사용할 필요가 없다면 설계를 유연하게 만들 당위성도 사라진다. 우선 역할, 책임, 협력을 고려하고, 객체의 역할과 책임이 자리잡힌 다음 마지막에 객체의 생성을 신경써라.

이 장에서 소개한 기법들을 적용하기 전에 역할, 책임, 협력의 모습이 명확하게 그려져야 한다.

 

댓글