8장에서는 다양한 의존성 관리 기법들을 소개했음.
9장에서는 원칙이라는 관점에서 정리
개방-폐쇄 원칙
컴파일타임 의존성을 고정시키고 런타임 의존성을 변경하라
컴파일 타임 의존성 = 인터페이스나 추상 함수에 의존
런타임 의존성 = OCP로 가능성을 확장하고 수정할 수 있는 구조
추상화가 핵심이다
추상화에 의존하는 것
변경에 의한 파급효과를 최대한 피하기 위해서는 변하는 것과 변하지 않는 것이 무엇인지를 이해하고 이를 추상화의 목적으로 삼아야만 한다.
생성 사용 분리
객체에 대한 생성과 사용을 분리해야 한다.
FACTORY 추가하기
객체 생성과 관련된 지식이 client에게 까지 새어나가기를 원하지 않는다.
객체 생성과 관련된 책임만 전담하는 별도의 객체 = FACTORY
Client는 오직 사용과 관련된 책임만 지고 생성과 관련된 어떤 지식도 가지지 않을 수 있다.
순수한 가공물에 책임 할당하기
Information expert에게 책임을 할당하기. 그렇게 하기 위해 적절한 후보가 존재하는지 찾아봐야 한다. Factory는 도메인 모델에 속하지 않음. 도메인 개념과는 아무런 상관이 없는 가공의 객체로 이동시킨 것. 객체를 분해하는 방식은 표현적 분해, 행위적 분해.
표현적 분해는 객체들을 이용해 시스템을 분해하는 것. 도메인과 소프트웨어 사이의 표현적 차이를 최소화하는 것을 목적으로 한다. 객체지향 설계의 가장 기본적인 접근법
그러나 모든 책임을 도메인 객체에게 할당하면 의존성과 관련된 문제점이 발생할 수 있음. 그러한 문제의 해결을 위해, 설계자의 편의를 위해 도메인과 무관한 인공적인 객체를 pure fabrication이라고 부른다.
인공적인 추상화들을 포함하므로, 실세계의 모방이 아니다.
의존성 주입
사용하는 객체가 아닌 외부의 독립적인 객체가 인스턴스를 생성한 후 이를 전달해서 의존성을 해결하는 방법을 의존성 주입이라고 부른다.
의존성 주입은 결국, 외부에서 사용할 구현체를 넣어주는 것. 사용하는 애는 인터페이스만 알고 있음
숨겨진 의존성은 나쁘다
Service Locator ⇒ 객체가 직접, service locator에게 의존성을 해결줄 것을 요청하여 해결 ( 외부에서 주입해주는 게 나아보인다..) → 의존성을 감추는 것이 문제 → 런타임에 문제가 발생할 수 있음
테스트 할때도 어려울 것 ( 싱글톤과 같은 문제?)
클래스의 사용법을 익히기 위해 구현 내부를 샅샅이 뒤져야 한다면 그 클래스의 캡슐화는 무너진 것이다.
Service locator를 사용해야하는 경우 → 의존성 주입을 사용못하는 경우. 깊은 호출 계층에 걸쳐 동일한 객체를 계속해서 전달해야 하는 고통을 견디기 어려운 경우.
⇒ 명시적인 의존성이 좋다(유연성에)
의존성 역전 원칙
상위 수준의 변경으로 하위 수준은 변경되도 되지만, 하위 수준의 변경으로 상위 수준은 변경이 되서는 안된다. 구체클래스는 의존성의 시작점이어야 한다. 의존성의 목적지가 돼서는 안 된다.
의존성 역전의 법칙
- 상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안된다. 둘 모두 추상화에 의존해야 한다.
- 추상화는 구체적인 사항에 의존해서는 안된다. 구체적인 사항은 추상화에 의존해야 한다.
전통적인 절차형 프로그래밍 → 구체적인 , 하위 모듈에 의존했지만,
객체지향 프로그래밍 → 추상적인, 상위 모듈에 의존해야 한다.(의존성 역전)
의존성 역전과 패키지
역전은 의존성의 방향뿐만 아니라, 인터페이스의 소유권에도 적용
인터페이스끼리 묶어서 패키지를 이루어야함. 왜냐하면 같은 패키지에 있으면, 구체 클래스를 변경해도 재빌드가 발생하기 때문. 퍼블릭 인터페이스를 포함하는 패키지는 다시 배포되는 주기가 구체 클래스의 패키지보다 길어야 할 것.
유연성에 대한 조언
유연한 설계는 유연성이 필요할 때만 옳다
유연한 설계 → 단숨함과 명확함의 미덕을 버리게 될 가능성이 높다.
유연성은 항상 복잡성을 수반한다.
정적인 프로그램과 동적인 프로세스 사이의 간극을 줄이기 위해 최선을 다해야 하며, 이를 가능하면 일치시켜야 한다.
협력과 책임이 중요하다
다양한 컨텍스트에서 협력을 재사용할 필요가 없다면 설계를 유연하게 만들 당위성도 함께 사라진다. 객체를 생성하는 방법에 대한 결정은 모든 책임이 자리 잡은 후 가장 마지막 시점에 내리는 것이 적절하다.
역할, 책임, 협력에 집중하라. 역할, 책임, 협력이 선명하게 그려지지 않는다면 의존성을 관리하는 데 들인 모든 노력이 물거품이 될 수도 있다는 사실을 명심하라.
'공부기록 > 객체지향' 카테고리의 다른 글
오브젝트 11장 - 합성과 유연한 설계 (0) | 2022.01.20 |
---|---|
오브젝트 10장 - 상속과 코드 재사용 (0) | 2022.01.18 |
오브젝트 8장 - 의존성 관리하기 (0) | 2022.01.17 |
오브젝트 7장 - 객체 분해 (0) | 2022.01.15 |
Class Adapter vs Object Adapter (0) | 2021.11.10 |