Request DTO에서 Entity를 생성할 때 의존성 방향을 반대로 하면 어떨까요?
3
작성한 질문수 5
안녕하세요.
Member 객체를 생성할 때, 다른 방법을 선택해 보는 것은 어떨까요?
기존에는(설계 트레이드 오프 개선 전) Member.register()가 MemberRegisterRequest에 직접 의존하고 있었는데, 도메인 모델이 요청 DTO를 알지 않도록 의존성을 반대로 두는 방법입니다.
MemberRegisterRequest에서 Member 객체를 직접 생성하는거죠.
public record MemberRegisterRequest(
...
) {
public Member toMember(PasswordEncoder passwordEncoder) {
return Member.register(email, nickname, password, passwordEncoder);
}
}public class Member extends AbstractEntity {
...
public static Member register(String email, String nickname, String password, PasswordEncoder passwordEncoder) {
Member member = new Member();
member.email = new Email(email);
member.nickname = requireNonNull(nickname);
member.passwordHash = requireNonNull(passwordEncoder.encode(password));
member.status = MemberStatus.PENDING;
member.detail = MemberDetail.create();
return member;
}
...
}public class MemberModifyService implements MemberRegister {
...
@Override
public Member register(MemberRegisterRequest registerRequest) {
checkDuplicateEmail(registerRequest);
Member member = registerRequest.toMember(passwordEncoder);
memberRepository.save(member);
sendWelcomeEmail(member);
return member;
}
...
}
MemberRegisterRequest.toMember(passwordEncoder)에서 Member.register(email, nickname, password, passwordEncoder)를 호출하면 Request DTO → Domain 방향으로만 의존합니다. 별도의 MemberRequestInfo 같은 파라미터 객체도 필요하지 않아 구현이 단순합니다.
Request DTO를 단순 데이터 전달 객체로 유지하려면 서비스 계층에서 각 값을 꺼내 Member.register()에 전달하는 방법도 가능합니다. (이 방법보다는 이전 방법이 서비스 계층을 간결하게 유지하는 방법이긴 합니다.)
이런 방법을 기본 개발 규칙으로 두면, 의존성 방향도 문제 없고, 추가적인 객체(예: MemberRequestInfo)를 생성할 필요도 없어서 충분한 이점이 있습니다.
다만, register()에 전달해야 할 파라미터가 많아진다면 번거롭긴 하겠네요.
이 방법에 대한 의견도 부탁 드립니다.
감사합니다.
답변 1
0
안녕하세요, 인프런 AI 인턴입니다. yamsroun님!
질문해주신 내용은 도메인 모델의 설계와 관련된 중요한 주제입니다. DTO와 엔티티 생성 간의 의존성 방향을 어떻게 설계하는 것이 좋을지에 대한 고민인데요. 해당 접근 방식에 대해 몇 가지 관점을 드려보겠습니다.
DTO에서 도메인으로의 의존성은 자연스럽다:
- 일반적으로 DTO는 외부 요청을 받아 내부 모델로 변환할 때 사용됩니다. 따라서 DTO가 도메인 객체를 생성하는 것은 불필요한 중간 객체를 줄일 수 있는 실용적인 설계입니다.
- 특히, 서비스 계층에서 DTO의 변환 논리를 담당할 경우, 서비스 메서드가 다소 간결해지고 가독성을 높일 수 있습니다.
- 일반적으로 DTO는 외부 요청을 받아 내부 모델로 변환할 때 사용됩니다. 따라서 DTO가 도메인 객체를 생성하는 것은 불필요한 중간 객체를 줄일 수 있는 실용적인 설계입니다.
의존성의 방향:
- 말씀하신 방법처럼, 실제로 외부 요청과 도메인 간의 구성을 명확히 하려면 의존성을 DTO에서 도메인으로 향하게 하는 것이 좋을 수 있습니다. 이는 도메인이 불필요하게 외부와 결합되는 것을 방지하는 역할도 합니다.
- 이렇게 하면 서비스 계층은 특정 DTO의 존재와 무관하게 자신의 역할에 집중할 수 있습니다.
- 말씀하신 방법처럼, 실제로 외부 요청과 도메인 간의 구성을 명확히 하려면 의존성을 DTO에서 도메인으로 향하게 하는 것이 좋을 수 있습니다. 이는 도메인이 불필요하게 외부와 결합되는 것을 방지하는 역할도 합니다.
서비스 계층의 책임 분리:
- 반면, 도메인 모델이 DTO 없이도 독립적으로 동작할 수 있는 상태로 관리하고 싶다면, 서비스 계층에서 각 값을 꺼내 전달하는 방식도 어느 정도 고려가 필요합니다. 하지만 이는 보일러플레이트 코드가 늘어날 수 있다는 단점이 있습니다.
- 반면, 도메인 모델이 DTO 없이도 독립적으로 동작할 수 있는 상태로 관리하고 싶다면, 서비스 계층에서 각 값을 꺼내 전달하는 방식도 어느 정도 고려가 필요합니다. 하지만 이는 보일러플레이트 코드가 늘어날 수 있다는 단점이 있습니다.
개발 규칙 설정의 융통성:
- 말씀하신 개발 규칙을 통해 팀 내 일관된 코딩 스타일을 확립하는 것이 중요합니다. 다만, 프로젝트의 성격나 팀의 코드베이스에 따라 어느 정도의 유연성이 필요할 수 있습니다.
- 말씀하신 개발 규칙을 통해 팀 내 일관된 코딩 스타일을 확립하는 것이 중요합니다. 다만, 프로젝트의 성격나 팀의 코드베이스에 따라 어느 정도의 유연성이 필요할 수 있습니다.
이 방식으로 모든 시스템에 적용하기 전에, 팀의 기술 수준과 유지보수 편의성을 고려하여 선택하시는 것이 좋을 것 같습니다.
질문 주신 주제와 관련하여, 토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1 강의에서도 이와 유사한 주제를 다루고 있사오니 참고하시기 바랍니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
파이썬 4강 질문입니다.
0
15
2
강의 화면이 안나와요
0
5
0
모의고사 1회 3번문제
0
47
3
41강 30:10
0
27
2
이론 공부법 질문 있습니다.
0
44
2
중급 과정 학습 중 복습과 진도 진행의 우선순위에 대해 질문드립니다
0
16
1
부모의 생성자 관련 질문
0
25
2
소스 코드 좀 올려주세요.
0
15
1
시험지 문제에 필기해도 되나요?
0
29
3
41강 11:23
0
30
2
4강파이썬 질문입니다
0
21
2
스프링 부트 버전 질문
0
21
2
try-catch 핸들러명
0
30
2
시간복잡도와 구현복잡도 관계
0
19
0
36강 3:48
0
35
2
35강 18:27
0
31
2
개념과 격벽에 대한 이해를 팀과 공유하고 합의하는 방법
1
35
2
자식 코드 내 super() 생략
0
40
2
빠져나오기 위해서 System.in을 닫는다는게 무슨 의민가요??
0
22
1
출력질문
0
46
2
31강 4:06
0
44
2
파이썬 학습자료가 강의 자료와 다릅니다.
0
73
3
섹션 2 - 9강 강의자료 다운로드 문제
0
53
3
29강 3:09
0
41
2





