04 유스케이스 구현하기
유스케이스 둘러보기
유스케이스에서 하는 일
- 입력을 받는다.
- 비즈니스 규칙을 검증한다. ← 도메인 엔티티와 이 책임을 공유함
- 모델 상태를 조작한다.
- 출력을 반환한다.
- 하나의 서비스가 하나의 유스케이스를 구현하고, 도메인 모델을 변경하고, 변경된 상태를 저장하기 위해 아웃고잉 포트를 호출
입력 유효성 검증
- command 내 생성자 or Validation API로 입력 유효성 검증
생성자의 힘
- Builder 보단 생성자를 활용하자 ← Builder를 쓰는게 오히려 실수하기 쉽다.
유스케이스마다 다른 입력 모델 사용하기
- ex) 계좌 등록하기 / 계좌 정보 업데이트하기
- 불변 command 객체에 null을 허용 + 유스케이스에 커스텀 유효성 검증 로직을 포함시켜야 함
- 각 유스케이스 전용 입력 모델을 사용하는게 훨씬 더 명확하게 만들고 다른 유스케이스와의 결합도를 제거하게 되어 불필요한 부수효과가 발생하지 않게 함
비즈니스 규칙 검증하기
- 입력 유효성 검증 vs 비즈니스 규칙 검증
- 비즈니스 규칙 검증
- 도메인 모델의 현재 상태에 접근해야 하면 ← 고맥락
- 유스케이스의 맥락 속에서 의미적인(semantical) 유효성 검증
- 도메인 엔티티 안에 포함 or 여의치 않으면 유스케이스 코드에서 도메인 엔티티 사용하기 전에 해도 괜찮
- 입력 유효성 검증
- 도메인 모델의 현재 상태에 접근할 필요가 없다면 ← 저맥락
- 구문상(syntactical) 유효성 검증
풍부한 도메인 모델 vs 빈약학 도메인 모델
- 도메인 로직을 도메인 엔티티에 구현할 지, 유스케이스에 구현할 지는 선택사항
유스케이스마다 다른 출력 모델
- 유스케이스를 가능한 한 구체적으로 유지하기 위해서는 정말 이 데이터를 반환해야 하는지 고민하자.
- 유스케이스들 간에 같은 출력 모델을 공유하게 되면 유스케이스들도 강하게 결합된다.
- 단일 책임 원칙을 적용하고 모델을 분리해서 유지하는 것이 유스케이스 결합을 제거하는 데 도움이 된다.
읽기 전용 유스케이스
- 인커밍 포트 + query service에 구현
- GetXXXQuery(incoming port), XXXPort(outgoing port)
05 웹 어댑터 구현하기
의존성 역전
- web adapter: imcoming, 외부로부터 요청을 받아 애플리케이션 코어를 호출하고 무슨 일을 해야 할지 알려줌
- web adapter → usecase ← service
- 어댑터가 동시에 두 가지 역할을 할 수도 있다. ← 인커밍 어댑터인 동시에 아웃고잉 어댑터가 될 수 있음
웹 어댑터의 책임
- HTTP 요청을 자바 객체로 매핑
- 권한 검사
- 입력 유효성 검증
- 웹 어댑터의 입력 모델을 유스케이스의 입력 모델로 변환할 수 있음을 검증
- 입력을 유스케이스의 입력 모델로 매핑
- 유스케이스 호출
- 유스케이스의 출력을 HTTP로 매핑
- HTTP 응답을 반환
컨트롤러 나누기
- 너무 적은 것보다는 너무 많은게 낫다.
- 클래스마다 코드는 적을수록 적다.
- 모든 연산을 단일 컨트롤러에 넣는 것은 데이터 구조의 재활용을 촉진하다. ← 그래서 모든 코드가 결국 결합하게 된다.
- 각 연산에 대해 가급적이면 별도의 패키지 안에 별도의 컨트롤러를 만드는 방식을 선호한다. 또한 가급적 메소드와 클래스명은 유스케이스를 최대한 반영해서 지어야 한다.
- 이런 전용 모델 클래스들은 컨트롤러의 패키지에 대해 private으로 선언할 수 있기 때문에 실수로 재사용될 일이 없다.
- 컨트롤러명과 서비스명에 대해서도 잘 생각해봐야 한다. ← Create.., Update.., Delete 만으로 충분히 의미를 드러낼 수 있는 유스케이스도 있겠지만, 한 번 더 숙고할 것. 더 명확한 이름이 없을까?