1장에서 얘기한 계층형 아키텍처의 단점들에 대한 대안을 말하기 전, SOLID 원칙 중 SRP(단일 책임 원칙)와 DIP(의존성 역전 원칙)에 대해 설명한다.
- 그냥 어렴풋이 "하나의 컴포넌트는 하나의 일을 수행한다" 로 알고 있던 이 원칙의 실제 정의는 달랐다.
- "컴포넌트를 변경하는 이유는 오직 하나뿐이어야 한다."
- 책에서 말하듯, 의미상 단일 책임 원칙 보다는 단일 변경 이유 원칙 이 더 적합해 보인다.
- 아키텍처 관점에서 컴포넌트를 변경하게 되는 이유가 두 개 이상인 경우는 어떤 경우일까?
- 바로 의존성에 의해 변경되는 경우이다.
- 컴포넌트 A가 컴포넌트 B에 의존하는 경우, B의 변경은 A의 변경으로도 이어진다. 결국, A의 기능이 아닌, B에 의해 변경되는 것이다.
- 그렇다면 이 의존성을 어떻게 해결할까? 이는 의존성 역전 원칙에 의해 해결이 가능하다.
- "코드 상의 어떤 의존성이든 그 방향을 역전시킬 수 있다."
- 도메인 계층이 영속성 계층의 의존성을 갖고 있다면 어떻게 역전시킬 수 있을까?
- 도메인 계층에 리포지토리에 대한 인터페이스를 만든다.
- 영속성 계층에서 이 리포지토리를 구현하게 한다.
- 위 원칙이 적용되려면 두 의존성을 모두 다룰 수 있어야 한다.
- 예를 들어, 서드파티 라이브러리의 경우는 해당되지 않는다.
- 위 두 원칙은 이후 설명할 클린 아키텍처의 핵심 기능이 된다.
- 비즈니스 규칙의 테스트를 용이하게 하고, 비즈니스 규칙은 프레임워크, 데이터베이스, UI기술, 그 밖의 외부 애플리케이션이나 인터페이스로부터 독립적이게 하는 아키텍처
- 이는 도메인 코드가 바깥으로 향하는 어떤 의존성도 없어야 함을 의미
- 의존성 역전 원칙의 도움으로 모든 의존성이 도메인 코드를 향하게 할 수 있다.
- 아키텍처의 코어에는 엔티티, 유스케이스를 중심으로 외부의 다른 컴포넌트들이 있다.
- 도메인 코드에서는 어떤 영속성 프레임워크나 UI 프레임워크가 사용되는지 알 수 없기 때문에 특정 프레임워크에 특화된 코드를 가질 수 없다.
- 이는 비즈니스 규칙에 집중할 수 있어, 도메인 코드를 자유롭게 모델링 할 수 있다.
- 반면, 도메인 계층은 철저히 외부와 분리되어야 하므로, 엔티티에 대한 모델을 각 계층에서 만들어 유지보수해야 한다.
- 코드량의 증가가 일어나지만, 외부와의 결합이 제거되어 독립적인 개발이 가능하고 유지보수를 용이하게 한다.
- 알리스테어 콕번이 클린 아키텍처의 원칙들을 조금 더 구체적으로 표현한 것이다.
- 육각형 코어에는 도메인 엔티티와 이와 상호작용하는 유스케이스가 있다.
- 육각형 외부에는 코어와 상호작용하는 어댑터들이 있다.
- 애플리케이션 코어는 이 어댑터들과 포트를 통해 상호작용한다.
- 애플리케이션 코어를 호출하는 어댑터는 입력 포트(인커밍 포트)를 통해 호출하고,
- 애플리케이션 코어가 호출하는 어댑터는 출력 포트(아웃고잉 포트)를 통해 호출된다.
- 이러한 구조로 인해 포트와 어댑터 아키텍처로도 알려져 있다.