들어가며
4편에서 외부에서 내부로 데이터를 보낼 것이라고 예고했다.
// request -> UseCase(inbounded port) -> Service (biz logic)
UseCase 인터페이스는 뭐하는 곳인가?
우선 인바운드 포트는 UseCase와 Command로 구성된다.
Controller에서 Request를 Port로 전달하는데, Port에서 이를 전달 받는 곳이 UseCase다.
그리고 UseCase는 Service가 비즈니스 로직을 수행할 수 있게 도움을 주는 역할을 한다.
public interface RegisterMembershipUseCase {
Membership registerMembership(RegisterMembershipCommand command);
}
registerMembership메서드는 Command 명령객체를 받아 Membership객체를 만든다고 정의되어 있다.
갑자기 Command라는 객체가 등장했다!
좋은 객체지향 프로그래밍 DIP 준수
Controller에서는 Request를 바로 UseCase로 전달하지 않고 Command 패턴을 사용한다.
이유는 의존성 역전 원칙을 준수하기 위해서다.
좋은 객체 프로그래밍은 서로간의 구체적인 의존을 피하고, 추상화에 의존해야 한다.
즉, Controller의 request가 변경되더라도 UseCase에는 영향을 주지 않아야 한다.
회원 등록을 위해 정보 캡슐화하기
@Builder
@Data
@EqualsAndHashCode(callSuper = false)
public class RegisterMembershipCommand extends SelfValidating<RegisterMembershipCommand> {
// except membershipId, isValid
@NotNull
private String name;
@NotNull
private String address;
@NotNull
private String email;
@AssertTrue
private boolean isValid;
private boolean isCorp;
public RegisterMembershipCommand(String name, String address, String email, boolean isValid, boolean isCorp) {
this.name = name;
this.address = address;
this.email = email;
this.isValid = isValid;
this.isCorp = isCorp;
this.validateSelf();
}
}
명령 객체를 사용하기 위해 RegisterMembershipCommand의 생성자를 초기화한다.
이제 RegisterMembershipCommand는 값을 받을 수 있다.
값으로 받을 name, address, email은 @NotNull로 빈값을 가지지 않음을 SelfValidating하고 있다.
빌더 패턴을 사용해 Command 객체 구현
RegisterMembershipCommand command = RegisterMembershipCommand.builder()
.name(request.getName())
.address(request.getAddress())
.email(request.getEmail())
.isValid(true)
.isCorp(request.isCorp())
.build();
다시 Controller로 돌아와서 request객체의 값을 get해서 빌더패턴을 통해 Command객체를 생성한다.
빌더 패턴은 선택적으로 필드값을 사용할 수 있고 순서에 영향을 받지 않는 등 유연한 장점을 갖는다.
생성자 주입을 통해 관계 설정
UseCase를 생성자 주입하여 만들어 둔 command객체를 통해 registerMembership메서드를 전달한다.
의존성 주입 방식으로 @RequiedArgsConsrtructor를 통해 생성자 주입을 사용하고 있다.
즉, Controller 클래스에서 UseCase 객체를 만들 수 있도록 한다.
@RequiredArgsConstructor
public class RegisterMembershipController {
private final RegisterMembershipUseCase registerMembershipUseCase;
registerMembershipUseCase.registerMembership(command);
'개발 방법론' 카테고리의 다른 글
MSA(마이크로 서비스 아키텍처) 멤버서비스 DB연동 [7] (0) | 2023.12.20 |
---|---|
MSA(마이크로 서비스 아키텍처) 멤버서비스 서비스층 개발 [6] (0) | 2023.12.19 |
MSA(마이크로 서비스 아키텍처) 멤버서비스 인바운드 어댑터 [4] (1) | 2023.12.19 |
MSA(마이크로 서비스 아키텍처) 멤버서비스 도메인 [3] (0) | 2023.12.18 |
MSA(마이크로 서비스 아키텍처)의 멀티 모듈과 DDD(도메인 주도 설계) [2] (0) | 2023.12.18 |