이전장까지
•
3장까지는 레이어드 아키텍처를 사용함으로써 발생하기 쉬운 문제점, 헥사고날 아키텍처가 추구하는 방향성에 대해서 살펴봄
이번장부터는
•
실제 헥사고날 아키텍처를 구현하면서 고려해야되는 부분과 기본적인 구현 방법에 대해서 설명
어디부터 설계할지
•
기존 레이어드 아키텍처는 가장 내부에 보통 DB가 있고 그 DB를 먼저 설계하고 그 윗 레이어를 설계
•
헥사고날 아키텍처에서는 유스케이스가 가장 가운데 있고 각각의 외부 계층과 느슨하게 연결
•
일단 도메인 엔티티부터 구현
일반적인 시나리오
1.
입력을 받는다
2.
비느지스 규칙을 검증한다
3.
모델 상태를 조작한다
4.
출력을 반환한다
•
각각의 과정에서 알야야되는 부분을 살펴본다
송금하기에서는
하나의 유즈케이스에 각각의 인, 아웃 포트가 붙는다.
유효성 검증과 비즈니스 규칙 검증은 다르다
•
유효성 검증이 도메인 로직을 오염시켜서는 안된다
•
입력 모델을 통해서 유효성 검증을 한다
•
유효성 검증에 Bean Validation API를 사용할 수 있다
•
유효성 검증은 단순하게 구문상의 유효성을 검증, 반면 비즈니스 규칙은 유스케이스 맥락 속 의미적인 유효성을 검증(ex: 출금 계좌는 초과 출금되어서는 안된다 vs 송금되는 금액은 0보다 커야한다)
생성자의 힘
•
생성자의 파라미터가 많은 경우 빌더패턴을 사용하면 편하다
•
하지만 IDE를 통한 컴파일러의 도움을 받지 못한다.
유즈케이스마다 다른 입력 모델
•
공통의 입력 모델을 사용하면 부수효과(사이드 이펙트)를 만들 수 있다
•
대신 이렇게 입력 모델이 많아지면 그에 대한 보일러플레이트 코드도 많아 질 수 있다
2가지 도메인 모델(풍부한 도메인 모델 vs 빈약한 도메인 모델)
•
빈약한 도메인 모델은 단순한 필드와 그에 대한 getter, setter만 포함. 도메인 로직은 유즈케이즈 클래스에 있다
•
풍부한 도메인 모델은 다양한 도메인 로직이 도메인 클래스에 있음
•
정답은 없다
유스케이스마다 다른 출력 모델
•
입력모델과 동일하게 출력모델도 유즈케이스마다 다르게 가져가야 한다
•
유즈케이스간에 출력모델을 공유하면 유즈케이스들이 강하게 결합한다
•
공유모델은 장기적으로 점점 커질 수 있다
읽기 전용 유스케이스는 어떨까?
•
쿼리를 위한 인커밍 전용 포트를 만들고 쿼리 서비스를 구현 할 수 있다
•
쓰기가 가능한 유스케이스와 분리해서 CQS 혹은 CQRS같은 개념을 적용할 수 있다
결론
•
각각의 유즈케이스를 나누고 유즈케이스별로 모델을 별도로 가져가는게 장기적으로 유지보수하는데 좋고 여러 명의 개발자가 다른 사람의 작업 중인 유스케이스를 건드리지 않고 동시 작업하는데 용이하다.
•
다만 각각의 유즈케이스, 각각의 모델을 따로 생성하기 때문에 더 많은 작업이 필요할 수 있다.