소개

2장: 의존성 역전하기

계층형 아키텍처의 문제점에 대해 다루어보았으니.. (계층간 강결합이 원인) 이제는 그 대안에 대한 이야기를 해본다.

SRP; Single Responsibility Principle

하나의 컴포넌트는 오로지 한 가지 일만 해야 하고, 그것을 올바르게 수행해야 한다.
→ 컴포넌트를 변경하는 이유는 오직 하나뿐이어야 한다.
만약 컴포넌트를 변경할 이유가 한 가지라면 우리가 어떤 다른 이유로 소프트웨어를 변경하더라도 이 컴포넌트에 대해서는 전혀 신경 쓸 필요가 없다.
하지만 변경할 이유라는 것은 컴포넌트 간의 의존성을 통해 너무도 쉽게 전파된다.
A는 여러 컴포넌트에 의존하고 있으며, E는 의존하는 것이 전혀 없다.
E를 변경할 유일한 이유는 새로운 요구사항에 의해 E의 기능을 바꿔야할 때 뿐이다.
A는 여러 이유에 의해 변경될 수 있다.

DIP; Dependency Inversion Principle

계층형 아키텍처에서 계층 간 의존성은 항상 다음 계층인 아래 방향을 가리킨다.
Web → Domain → Persistence
단일 책임 원칙을 고수준에서 적용할 때 상위 계층들이 하위 계층들에 비해 변경할 이유가 더 많아진다는 의미다.
→ 영속성 계층에 대한 도메인 계층의 의존성 때문에 영속성 계층을 변경할 때마다 잠재적으로 도메인 계층도 변경해야한다.
How? → DIP
엔티티는 도메인 객체를 표현하고 도메인 코드는 이 엔티티들의 상태를 변경하는 일을 중심으로 한다.
그렇기 때문에 먼저 엔티티를 도메인 계층으로 올린다.
그러나 영속성 계층의 리포지토리가 도메인 계층에 있는 엔티티에 의존하기 때문에 두 계층 사이에 순환 의존성이 생긴다.
도메인 계층에 리포지토리에 대한 인터페이스를 만들고, 실제 리포지토리는 영속성 계층에서 구현하게 하면 해결.
기존: 도메인 코드가 영속성 코드를 의존
변경: 영속성 코드가 도메인 코드를 의존
→ 영속성 계층의 코드에 있는 의존성으로부터 도메인 로직을 해방

클린 아키텍처

로버트 C. 마틴의 정의
클린 아키텍처는 비즈니스 규칙의 테스트를 용이하게 한다
비즈니스 규칙은 프레임워크, 데이터베이스, UI 기술, 그 밖의 외부 애플리케이션이나 인터페이스로부터 독립적일 수 있다
즉, 도메인 코드가 바깥으로 향하는 어떤 의존성도 없어야 함을 의미한다. 대신 DIP의 도움으로 모든 의존성이 도메인 코드를 향하고 있다
결국,
의존성 규칙을 따름으로써 관심사가 분리된다
본질적으로 테스트하기 쉬운 시스템을 만들 수 있다
도메인 주도 설계를 가장 순수한 형태로 적용해 볼 수 있는 구조이다.
물론 이러한 아키텍처가 공짜는 아니다.
영속성 계층에 데이터베이스의 구조와 컬럼 매핑을 서술한 엔티티 클래스가 있더라도,
도메인 계층에서는 영속성 계층을 모르기 때문에 도메인 계층에서 사용할 엔티티를 만들어야 한다.
이는 모든 계층에서 동일하게 적용된다.

육각형 아키텍처(헥사고날 아키텍처)

사실 클린 아키텍처 개념보다 먼저 등장.
클린 아키텍처와 비슷한 내용을 주장하였으나 너무 어려워서 세상 저 멀리에 있다가 로버트 C. 마틴이 더 쉽게 풀어내며 발굴 됨
구조
안에는 도메인 엔티티와 이와 상호작용하는 유스케이스가 있다.
외부로 향하는 의존성이 없기 때문에 마틴이 제시한 클린 아키텍처의 의존성 규칙이 그대로 적용된다
바깥에는 어댑터들이 있다.
왼쪽에 있는 어댑터들은 코어를 호출하기 때문에 애플리케이션을 주도하는 어댑터이다.
오른쪽에 있는 어댑터들은 애플리케이션 코어에 의해 호출되기 때문에 애플리케이션에 의해 주도되는 어댑터이다.

Conclusion

의존성을 역전시켜 도메인 코드가 다른 바깥쪽 코드에 의존하지 않게 함
이를 통해 영속성과 UI에 특화된 모든 문제로부터 도메인 로직의 결합을 제거하고 코드를 변경할 이유의 수를 줄일 수 있음
또한 도메인 코드는 비즈니스 문제에 딱 맞도록 자유롭게 모델링될 수 있고, 영속성 코드와 UI코드도 각 문제에 맞게 모델링될 수 있다