DTO란
- 계층간 데이터 교환을 위해 사용하는 객체
God Class에 대한 용어 정리
크기가 커야 god class인 것은 아니다. 여러 Layer에 걸쳐 사용되거나, 2개 이상의 책임을 가진다면 이는 god class이다.
1. Domain과 DTO를 분리해야 하는 이유
- 하나의 거대한 범용 class를 여러 Layer에 걸쳐 사용하게 된다.
- 특정 상황에서 특정 값만이 존재하는 필드
- member 정보를 가져오지 않고 card 정보만 가져요는 쿼리가 별도로 존재한다. 하지만, member 필드까지 참고해야 한다.
- 시스템에 항상 완벽하게 초기화 된 상태의 객체만 존재하기 어렵다.
- 특정 상황에서 특정 값만이 존재하는 필드
- 초기화되는 시점과 사용되는 시점이 필드군마다 제각각이기에 유지보수가 어렵다.
- 다른 도메인 책임까지 넘보게 된다.
2. 해결책) god class를 피하기 위해 Domain과 DTO를 분리하자
- 유지보수가 쉬운 시스템 : 수정이 발생했을 때, 필요한 부분만 수정해도 문제가 해결되는 시스템
2-1. ★ 변경 대상 클래스 숫자가 늘어나면 나쁜 설계가 아닌가?
- 1개의 god class를 3개의 DTO, Domain Model로 쪼갰다고 가정하자. 이 때, 3개 클래스 모두 변경을 유발하는 하느의 수정 케이스를 더올리며, 변경 대상 클래스가 1개에서 3개에서 늘어나니 이 것은 유지보수 포인트가 늘어나는 나쁜 설계가 아닌가하는 생각이 들 수 있다.
→ 중요한 것은!! 클래스의 물질적인 개수가 아니다.
- 지향점은 수정 시 변경 대상 클래스의 수가 적어지는 설계가 아니다. 필요한 부분만 집중해서 변경할 수 있게끔 변경의 범위를 제한해주는 설계, 책임으로 도메인 모델을 망치지 않는 설계가 중요하다. (• [리팩터링 2판] 3장 Bad Smells in Code - 뒤엉킨 변경, 산탄총 수술 참고)
3. 그렇다면, 항상 Domain과 dto를 분리하는 것이 좋은 설계인가?
- DTO의 종류
- ResponseDTO (Presentation DTO)
- RequestDTO (Persistence DTO)
- ResponseDTO와 Domain은 분리해야하는 경우가 많다.
- 분리하지 않아도 되는 케이스 대부분, 나중에 분리가 필요해지는 케이스일 가능성이 높다.
- 표현과 도메인 모델은 불일치 가능성이 높다.
- RequestDTO와 Domain은 굳이 분리하지 않아도 되는 경우가 많다.
- 대부분 쿼리 join 정도로 Domain Model에 변형을 가하지 않고 잘 매핑하도록 만들 수 있다.
- Persistence Layer의 요구사항으로 인해 Domain Model을 망칠 가능성이 적다.
- 분리해야 하는 경우
- 두 도메인 모델에 필요한 데이터를 한번에 가져오는 경우 [MyBatis] 객체 안의 객체 매핑하기 (ResultMap과 DTO)
- 하나의 도메인 모델을 두 테이블에 나누어 저장하는 경우 Repository와 DataMapper의 책임 (w/o ORM)
4. 패키지 관리
- 도메인을 너무 작게 나누면 두개 이상의 도메인에서 공통으로 사용하는 클래스를 어디에 위치시킬지 애매해질 수 있다.
{domain}
ㄴ model
ㄴ dto
ㄴ presentation
ㄴ persistence // 필요한 경우에만 만든다
ㄴ external
{domain2}
ㄴ ...
[마틴파울러] Layering 관련 글 모음 - '도메인을 최우선으로 나누고...' 부분 참고
결론
- ResponseDTO : Domain Model로부터 항상 분리한다.
- RequestDTO : 필요한 경우에만 분리한다.
- 분리해야 하는 케이스가 드물며, 분리하도록 강제한다면 이를 불편하고 불필요한 작업이라 느낄 수 있다.
참고
'공부 > Spring' 카테고리의 다른 글
[chap2] 스프링 (0) | 2022.05.20 |
---|---|
JdbcTemplate를 사용하는 이유 (3) | 2022.05.08 |
[Java] @Transaction(readOnly=true)을 사용하면 성능이 향상되는 이유 (4) | 2022.05.07 |
[Spring] @Transactional (0) | 2022.04.29 |
[Spring] DB연동 없이 DB테스트 수행하기 (0) | 2022.04.29 |
댓글