소개

4장: 유스케이스 구현하기

이전장까지

3장까지는 레이어드 아키텍처를 사용함으로써 발생하기 쉬운 문제점, 헥사고날 아키텍처가 추구하는 방향성에 대해서 살펴봄

이번장부터는

실제 헥사고날 아키텍처를 구현하면서 고려해야되는 부분과 기본적인 구현 방법에 대해서 설명

어디부터 설계할지

기존 레이어드 아키텍처는 가장 내부에 보통 DB가 있고 그 DB를 먼저 설계하고 그 윗 레이어를 설계
헥사고날 아키텍처에서는 유스케이스가 가장 가운데 있고 각각의 외부 계층과 느슨하게 연결
일단 도메인 엔티티부터 구현

일반적인 시나리오

1.
입력을 받는다
2.
비느지스 규칙을 검증한다
3.
모델 상태를 조작한다
4.
출력을 반환한다
각각의 과정에서 알야야되는 부분을 살펴본다

송금하기에서는

하나의 유즈케이스에 각각의 인, 아웃 포트가 붙는다.

유효성 검증과 비즈니스 규칙 검증은 다르다

유효성 검증이 도메인 로직을 오염시켜서는 안된다
입력 모델을 통해서 유효성 검증을 한다
유효성 검증에 Bean Validation API를 사용할 수 있다
유효성 검증은 단순하게 구문상의 유효성을 검증, 반면 비즈니스 규칙은 유스케이스 맥락 속 의미적인 유효성을 검증(ex: 출금 계좌는 초과 출금되어서는 안된다 vs 송금되는 금액은 0보다 커야한다)

생성자의 힘

생성자의 파라미터가 많은 경우 빌더패턴을 사용하면 편하다
하지만 IDE를 통한 컴파일러의 도움을 받지 못한다.

유즈케이스마다 다른 입력 모델

공통의 입력 모델을 사용하면 부수효과(사이드 이펙트)를 만들 수 있다
대신 이렇게 입력 모델이 많아지면 그에 대한 보일러플레이트 코드도 많아 질 수 있다

2가지 도메인 모델(풍부한 도메인 모델 vs 빈약한 도메인 모델)

빈약한 도메인 모델은 단순한 필드와 그에 대한 getter, setter만 포함. 도메인 로직은 유즈케이즈 클래스에 있다
풍부한 도메인 모델은 다양한 도메인 로직이 도메인 클래스에 있음
정답은 없다

유스케이스마다 다른 출력 모델

입력모델과 동일하게 출력모델도 유즈케이스마다 다르게 가져가야 한다
유즈케이스간에 출력모델을 공유하면 유즈케이스들이 강하게 결합한다
공유모델은 장기적으로 점점 커질 수 있다

읽기 전용 유스케이스는 어떨까?

쿼리를 위한 인커밍 전용 포트를 만들고 쿼리 서비스를 구현 할 수 있다
쓰기가 가능한 유스케이스와 분리해서 CQS 혹은 CQRS같은 개념을 적용할 수 있다

결론

각각의 유즈케이스를 나누고 유즈케이스별로 모델을 별도로 가져가는게 장기적으로 유지보수하는데 좋고 여러 명의 개발자가 다른 사람의 작업 중인 유스케이스를 건드리지 않고 동시 작업하는데 용이하다.
다만 각각의 유즈케이스, 각각의 모델을 따로 생성하기 때문에 더 많은 작업이 필요할 수 있다.