계층형 아키텍처의 문제점에 대해 다루어보았으니.. (계층간 강결합이 원인) 이제는 그 대안에 대한 이야기를 해본다.
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코드도 각 문제에 맞게 모델링될 수 있다