책 일지/만들면서 배우는 클린 아키텍쳐

8장 경계 간 매핑하기

worldi 2024. 1. 9. 18:58

매핑하지 않기 전략 (No Mapping)

웹, 애플리케이션, 영속성 계층 모두에서 도메인 모델을 입출력 모델로 쓰는 것이다. 이는, 단일 책임 원칙을 위반한다.

절대로 쓰면 안되는 건 아니고, 간단한 CRUD 유스케이스 같은 경우, 모든 계층이 정확히 같은 구조의, 같은 정보를 필요로 한다면 괜찮다.

양방향 매핑 전략

각 계층이 전용 모델을 가진 매칭 전략을 양방향 매핑 전략이라고 한다.

각 어댑터가 해당 모델을 도메인 모델로, 도메인 모델을 해당 모델로 매핑할 책임을 가지고 있다. 모두 양방향으로 매핑한다.

장점

  • 각 계층이 전용 모델을 변경하더라도, 다른 계층에는 영향이 없다.
  • 웹이나 영속성 관심사로 오염되지 않는 깨끗한 도메인 모델로 이어진다.
  • 매핑하지 않기 전략 다음으로 간단한 전략이다.

단점

  • 보일러 플레이트 코드가 생긴다. 매핑을 구현하는 데에 시간이 든다.
  • 도메인 모델이 계층 경계를 넘어서 통신하는 데 사용된다. 즉, 도메인 객체가 인커밍 포트와 아웃고잉 포트의 입력 파라미터와 반환값으로 사용된다. → 이는, 바깥쪽 계층의 요구에 따른 변경에 취약해진다.

완전 매핑 전략

각 연산마다 별도의 입출력 모델을 사용한다. 웹 어댑터와 애플리케이션 계층 각각이 자신의 전용 모델을 각 연산을 실행하는 데 필요한 모델로 매핑한다.

  • 웹 계층은 입력을 애플리케이션 계층의 커맨드 객체로 매핑할 책임을 가진다.
  • 각 유스케이스는 전용 필드와 유효성 검증 로직을 가진 전용 커맨드를 가진다.
  • 애플리케이션 계층은 커맨드 객체를 유스케이스에 따라 도메인 모델을 변경하기 위해 필요한 모델로 매핑할 책임을 가진다.

장점

  • 유지보수가 쉽다.

단점

  • 하나의 웹 모델과 도메인 모델 간의 매핑 보다 더 많은 코드가 필요

전역 패턴으로 추천하지는 않는다. 웹계층과 애플리케이션에서는 추천! (상태 변경 유스케이스가 명확할 때)

하지만, 애플리케이션 계층과 영속성 계층 사이에서는 매핑 오버헤드가 있다…

단방향 매핑 전략

모든 계층의 모델들이 같은 인터페이스를 구현한다.

인터페이스는 특성에 대한 getter 메서드를 제공해서, 도메인 모델의 상태를 캡슐화 한다.

  • 도메인 모델은 풍부한 행동 구현할 수 있다. 도메인 객체는 인터페이스를 구현하고 있기 떄문에, 인커밍/ 아웃 포트가 기대하는 대로 행동한다.
  • 바깥 계층에서는 상태 인터페이스에 의핸 도메인 상태를 변경하지 않는다.
  • 바깥 계층 → 애플리케이션 계층으로 전달 되는 객체들도 상태 인터 페이스를 구현한다. 이 매핑은 DDD 개념과 잘 어울린다. → Factory
  • 각 계층은 한 방향으로만 매핑 (단방향) 한다. 한 계층이 다른 계층으로 부터 객체를 받으면, 해당 계층에서 이용할 수 있도록, 다른 무언가로 매핑한다.
  • 계층 간의 모델이 비슷할 때 효과적이다.
    • ex) 읽기 전용 연산의 경우, 상태 인터페이스가 필요한 모든 정보를 제공한다. 따라서 웹 계층에서 전용 모델로 매핑할 필요가 없다.

언제 어떤 매핑 전략을 사용할까?

그때 마다 다르다. 매핑 전략을 전역 규칙으로 정의해서는 안된다.

예를 들어서 변경 유스케이스와 쿼리 유스케이스를 다른 매핑 전략으로 가져갈 수 있다.

변경 유스 케이스

  • 웹 계층과 애플리케이션 사이에서는 유스케이스의 결합을 제거하기 위해 완전 매핑 전략을 첫 번째 선택지로 둘 수 있다. → 유스케이스 별 유효성 검증 로직이 명확해진다. 필요한 필드만 다룬다.
  • 애플리케이션과 영속성 계층 사이에서는 매핑 오버해드를 줄이기 위해 ‘매핑하지 않기’ 전략을 첫번째 선택지로 둔다. → but 애플리케이션 계층에서 영속성 문제를 다뤄야 한다면, 양방향 매핑전략으로 바꾼다.

쿼리 유스케이스

  • 매핑 오버헤드를 줄이고 빠르게 짜기 위해 매핑하지 않기 전략을 첫번째로 가져간다. (웹-애플리케이션, 애플리케이션-영속성 계층)
  • 하지만, 애플리케이션 계층에서 영속성, 또는 웹 문제를 다룬다면 양방향 매핑 전략으로 바꾼다.

유지보수 가능한 소프트웨어를 만드는 데 어떻게 도움이 될까?

  • 인커밍, 아웃코잉 포트는 서로 다른 계층이 어떻게 통신해야 하는 지 정의한다. 계층 사이에 매핑을 수행할 지 여부와 어떤 매핑 전략을 선택할지가 포함된다.
  • 각 유스케이스에 대해 좁은 포트를 사용하면, 유스케이스마다 다른 매핑 전략을 사용할 수 있고, 다른 유스케이스에 영향을 미치지 않으면서 코드 개선할 수 있다.
  • 상황별로 매핑전략을 선택해야 한다. → 유지보수하고 쉬운 코드를 이끈다.