8장에서 배운 의존성 관리기법들을 정리하는 챕터라고 생각
이름을 가진 설계 원칙을 통해 기법들을 정리
개방-폐쇄 원칙(open-closed principle)(OCP)
확장 가능하고 변화에 유연하게 대응할 수 있는 설계
- 확장에 열려 있다 : '동작'을 추가해서 기능을 확장
- 수정에 대해 닫혀 있다 : '코드'를 수정하지 않고 동작을 추가하거나 변경
유연한 설계란 기존의 코드를 수정하지 않고도 애플리케이션의 동작을 확장할 수 있는 설계
컴파일타임 의존성을 고정시키고 런타임 의존성을 변경하라
의존성 관점에서 개방-폐쇄 원칙을 따르는 설계
- 컴파일타임 의존성은 유지하면서 런타임 의존성의 가능성을 확장하고 수정할 수 있는 구조
추상화가 핵심이다
개방-폐쇄 원칙의 핵심은 추상화에 의존하는 것
추상화란 핵심적인 부분만 남기고 불필요한 부분은 생략함으로써 복잡성을 극복하는 기법
추상화의 결과물 : 다양한 상황에서의 공통점
의존성의 방향이 중요하다 : 모든 요소가 추상화에 의존해야 한다
변경에 의한 파급효과를 최대한 피하기 위해서는
- 변하는 것과 변하지 않는 것이 무엇인지를 이해하고 이를 추상화의 목적으로 삼는 것
생성 사용 분리
객체의 생성은 피할 수 없다 : 부적절한 곳에서 객체를 생성하는 것이 문제다
동일한 클래스 안에서 객체 생성과 사용이 공존하면 안 된다
생성과 사용 분리 방법
- 생성할 책임을 클라이언트로 옮기는 것
FACTORY 추가
객체 생성과 관련된 책임만 전담하는 별도의 객체 추가 : FACTORY
순수한 가공물에게 책임 할당하기
책임 할당의 가장 기본이 되는 원칙은 책임을 수행하는 데 필요한 정보를 가장 많이 알고 있는 INFORMATION EXPERT에게 책임을 할당하는 것
도메인 모델은 INFORMATION EXPERT를 찾기 위해 참조할 수 있는 일차적인 재료
FACTORY는 도메인 모델이 아니다, 기술적인 객체이다
시스템 객체를 분해하는 두 가지 방식
- 표현적 분해(representational decomposition)
- 도메인 모델에 담겨 있는 개념과 관계를 따름
- 객체지향 설계를 위한 가장 기보적인 접근법
- 행위적 분해(behavioral decomposition)
- 모든 책임을 도메인 객체로 할당하기 어려운 경우에 사용됨
- 어떤 행동을 추가하려고 하는데 행동을 책임질 마땅한 도메인 개념이 존재하지 않는 경우
- PURE FABRICATION 순수한 가공물
- 책임을 할당하기 위해 창조되는 도메인과 무관한 인공적인 객체
의존성 주입
의존성 주입은 의존성을 해결하기 위해 의존성을 객체의 퍼블릭 인터페이스에 명시적으로 드러내서
외부에서 필요한 런타임 의존성을 전달할 수 있도록 만드는 방법을 포괄하는 명칭
숨겨진 의존성은 나쁘다
숨겨진 의존성은 캡슐화를 위반한다
명시적인 의존성이 숨겨진 의존성보다 좋다
의존성 역전 원칙
추상화와 의존성 역전
의존성 역전 원칙(Dependency Inversion Principle)(DIP)
- 상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안 된다. 둘 모두 추상화에 의존해야 한다
- 추상화는 구체적인 사항에 의존해서는 안 된다. 구체적인 사항은 추상화에 의존해야 한다
역전(Inversion)
- 전통적인 소프트웨어 개발 방법은 상위모듈이 하위모듈에 의존(top down)
- 잘 설계된 객체지향 프로그램의 의존성 구조는, 전통적인 절차적 구조에 역전된 것
의존성 역전 원칙과 패키지
의존성의 뱡향뿐만 아니라 인터페이스의 소유권에도 적용
인터페이스의 소유권을 서버가 아닌 클라이언트에 위치
유연성에 대한 조언
유연한 설계는 유연성이 필요할 때만 옳다
협력과 책임이 중요하다
초보자가 자주 저지르는 실수 중 하나는 객체의 역할과 책임이 자리를 잡기 전에 너무 성급하게 객체 생성에 집중하는 것이다
객체를 생성하는 방법에 대한 결정은 모든 책임이 자리를 잡은 후 가장 마지막 시점에 내리는 것이 적절하다