매핑에 찬성하는 개발자
- 두 계층 간에 매핑을 하지 않으면 양 계층에서 같은 모델을 사용해야 함
- 이렇게 하면 두 계층이 강하게 결합됨
매핑에 반대하는 개발자
- 두 계층 간 매핑을 하게 되면 보일러플레이트 코드가 너무 많이 발생
- 대부분의 유스케이스는 CRUD만 사용하고, 계층에 걸쳐 같은 모델을 사용하기 때문에 계층 사이 매핑은 필요 없다.
매핑이 반드시 필요한 것은 아님
- 상황에 맞게 적절한 전략을 사용할 필요가 있다.
매핑하지 않기 전략
웹 계층 ↔ 애플리케이션 계층 ↔ 영속성 계층에서 모두 동일한 모델을 사용

장점
- 보일러플레이트 코드가 없어 코드양이 줄고, 작성이 간편
단점
- 도메인 모델에서 웹 계층의 요구사항(JSON 적렬화, ..)과 영속성 계층의 요구사항(key, manyToOne, ..)을 모두 적용해야 함
- 해당 클래스는 결국, 웹, 애플리케이션, 영속성 계층에서의 여러 이유들로 인해 변경되어야 함
- 단일 책임 원칙을 위배
- 또한 각 계층에서 특정 커스텀 필드를 두고 싶은 경우에, 다른 계층에서는 사용되지 않는 필드를 추가해야 함
이러한 단점에도 불구하고, 모든 계층에서 “같은 구조, 같은 정보”를 필요로 한다면 “매핑하지 않기” 전략은 완벽한 선택지
- 하지만 이후에 애플리케이션 계층이나 도메인 계층에서 웹과 영속성 문제를 다루게 되면, 곧바로 다른 전략을 취해야 한다.
양방향 매핑 전략
서로 다른 두 계층이 전용 모델을 사용하는 방식

- 웹 계층에서는 웹 모델을 인커밍 포트에서 필요한 도메인 모델로 매핑
- 영속성 계층에서는 영속성 모델을 아웃고잉 포트에서 필요한 도메인 모델로 매핑
장점
- 각 계층이 전용 모델을 가지고 있기 때문에 각 계층이 전용 모델을 변경하더라도 다른 계층에는 영향이 없다.
- 각 모델 간의 단일 책임 원칙을 만족
단점
- 많은 보일러플레이트 코드가 발생
- 도메인 모델이 계층 경계를 넘어서 사용됨
- 인커밍 포트와 아웃고잉 포트는 도메인 객체를 입력 파라미터 또는 반환값으로 사용하기 때문
- 도메인 모델이 변경되는 경우, 다른 계층에도 변경사항이 전파될 수 있음
- 도메인 모델이 바깥쪽 계층의 요구에 따라 변경되어야 할 수도 있음
양방향 매핑 전략은 전략이 명료하고, 신성한 법칙처럼 여겨지기도 함
- 하지만 양방형 매핑 전략은 간단한 로직에서도 지나치게 많은 보일러 플레이트 코드와 복잡성을 증가시키기 때문에 적절한 고려가 필요하다.
완전 매핑 전략
각 연산마다 별도의 입출력 모델을 사용하는 방식

- 각 유스케이스에서는 전용 필드와 유효성 검증 로직을 가진 전용 Command를 가짐
- 웹 계층은 입력을 애플리케이션 계층의 “Command”로 매핑
- 실제 도메인 모델로의 매핑은 Service에서 수행
- 영속성 계층은 출력을 애플리케이션 계층의 “Command”로 매핑
- 실제 도메인 모델로의 매핑은 Service에서 수행
장점
- 여러 유스케이스의 요구사항을 함께 다뤄야 하는 경우에 구현 및 유지보수가 쉽다.
- 각 유스케이스 별로 전용 Command를 구현하기 때문에
- 도메인 모델이 다른 계층에서 사용되지 않음
- 도메인 모델이 변경되어도 변경이 다른 계층으로 전파되지 않음
- 도메인 모델이 바깥 계층의 요구에 따라 변경되지 않음
단점
- 애플리케이션 계층과 영속성 계층 사이에서는 매핑 오버헤드 때문에 사용하지 않는 것이 좋음
- 보일러 플레이트 코드가 많아짐
- 특정한 경우에는 입력에 대해서만 입력 모델 매핑을 하고, 출력은 도메인 객체를 그대로 반환해도 좋다.
- 도메인 객체의 모든 정보가 필요하고, 별도의 웹계층 요구사항이 없는 경우
단방향 매핑 전략
모든 계층의 모델이 같은 인터페이스를 구현한 모델을 사용하는 방식

- 해당 인터페이스에서는 관련 있는 특성에 대한 getter 메서드를 제공해 도메인 모델의 상태를 캡슐화
- 웹 계층은 입력받은 웹 모델을 그대로 UseCase에 전달
- Service에서는 전달받은 입력값을 기반으로 도메인 모델로 변환
- 영속성 계층으로 도메인 모델을 그대로 전달
- 영속성 계층에서는 전달받은 모델을 기반으로 영속성 모델 생성 후, 반환
장점
- 도메인 객체를 바깥 객체으로 전달하고 싶은 경우, 매핑 없이 그대로 전달할 수 있다.
- 바깥 계층에서는 전달 받은 상태 인터페이스를 그대로 사용할 것인지, 별도의 전용 모델로 매핑할 것인지를 결정할 수 있다.
- 상태 인터페이스에서는 행동을 변경하는 것을 노출하지 않았기 때문에 도메인 객체의 상태가 변경되지 않음
매핑 전략을 선택하는 방법
- 전체 프로젝트에 걸쳐서 모두 동일한 매핑 전략을 사용하는 것은 좋지 않다.
- 각 매핑 전략마다 장단점이 존재하기 때문에 한 전략을 전체 코드에 대한 규칙으로 설정하는 것은 좋지 않다.
- 어제 선택한 전략이 오늘은 최선이 아닐 수 있기 때문에 고정된 매핑 전략을 유지하기보다는 빠르게 코드를 짤 수 있는 간단한 전략으로 시작해서 계층 간 결합을 떼어낼 수 있는 복잡한 전략으로 리팩토링해가는 것도 좋은 방법이다.
- 언제 어떤 전략을 사용할 것인지에 대한 팀 내 가이드라인을 정하는 것이 좋다.
- 또한 왜 해당 전략을 최우선으로 택해야 하는지도 설명할 수 있어야 함
'Architecture(아키텍처)' 카테고리의 다른 글
| [만들면서 배우는 클린 아키텍처] 아키텍처 경계 강제하기 (2) | 2024.07.20 |
|---|---|
| [만들면서 배우는 클린 아키텍처] 09. 애플리케이션 조립하기 (0) | 2024.07.20 |
| [만들면서 배우는 클린 아키텍처] 07. 아키텍처 요소 테스트하기 (0) | 2024.07.20 |
| [만들면서 배우는 클린 아키텍처] 06. 영속성 어댑터 구현하기 (0) | 2024.07.20 |
| [만들면서 배우는 클린 아키텍처] 05. 웹 어댑터 구현하기 (0) | 2024.07.20 |