[Book] 만들면서 배우는 클린 아키텍처 - 2

2024. 12. 11. 00:02·Book
반응형

만들면서 배우는 클린 아키텍처의 8장을 읽고 내용을 작성했다. 아직 정리하면서 이해까지는 하지 못했는데, 나중에 프로젝트에 여러 매핑 전략을 사용하면 체득이 될 것 같다.


매핑 전략

  • 서로 다른 계층(웹, 애플리케이션, 도메인, 영속성 등)간 데이터가 어떻게 변환되고 전달될지를 정의
  • 각 계층이 자신의 관심사에만 집중할 수 있게 하고, 한 계층의 변경이 다른 계층에 미치는 영향을 최소화 해야한다.
  • 적절한 매핑 전략을 선택함으로써 단일 책임 원칙을 지키고, 코드의 유지보수성과 확장성을 높일 수 있다.

매핑하지 않기 전략

  • 웹 계층의 웹 컨트롤러가 SendMoneyUseCase 인터페이스를 호출해서 유스케이스를 실행
    • 이 인터페이스는 Account 객체를 인자로 가진다
  • 웹 계층, 애플리케이션 계층, 영속성 계층 모두 동일한 모델을 사용
  • 결과는?
    • 웹 계층과 영속성 계층은 모델에 특별한 요구사항이 있을 수 있다
      • 웹 계층에서 REST로 모델을 노출시켰다면 모델을 JSON으로 직렬화하기 위한 애노테이션을 특정 필드에 추가해야 할 수도 있다
      • 영속성 계층도 마찬가지: ORM 프레임워크를 사용하면 데이터베이스 매핑을 위한 애노테이션이 필요할 것이다
    • 도메인과 애플리케이션 계층은 웹이나 영속성과 관련된 특수한 요구사항에 관심이 없음에도 불구하고 Account 도메인 모델 클래스는 이런 모든 요구사항을 다뤄야 한다
      • Account 클래스는 웹, 애플리케이션, 영속성 계층과 관련된 이유로 인해 변경돼야 하기 때문에 단일 책임 원칙을 위배한다
  • 매핑하지 않는 전략을 절대 쓰면 안 되는 걸까? 그렇지는 않다
    • 모든 계층이 정확히 같은 구조의, 정확히 같은 정보를 필요로 한다면 적합하다
    • 하지만 애플리케이션 계층이나 도메인 계층에서 웹과 영속성 문제를 다루게 되면 곧바로 다른 전략을 취해야 한다
    • 어떤 매핑 전략을 선택했더라도 나중에 언제든 바꿀 수 있다
      • 저자의 경험에 따르면 많은 유스 케이스들이 간단한 CRUD 유스케이스로 시작했다가 시간이 지남에 따라 더 값비싼 매핑 전략이 필요한 경우가 많다

양방향 매핑 전략

  • 각 계층이 전용 모델을 가진 매핑 전략
  • 각 어댑터가 전용 모델을 가지고 있어서 해당 모델을 도메인 모델로, 도메인 모델을 해당 모델로 매핑할 책임을 가진다
  • 각 계층이 전용 모델을 가지고 있는 덕분에 각 계층이 전용 모델을 변경하더라도 다른 계층에는 영향이 없다 (내용을 변경하지 않는 한)
    • 웹 모델은 데이터를 최적으로 표현하는 구조를 가질 수 있고
    • 도메인 모델은 유스케이스를 제일 잘 구현할 수 있는 구조를 가질 수 있다
    • 영속성 모델은 데이터베이스에 객체를 저장하기 위해 ORM에서 필요로 하는 구조를 가질 수 있다
  • 단일 책임 원칙을 만족
  • 매핑하지 않기 전략 다음으로 간단한 전략
    • 매핑 책임이 명확: 바깥 계층은 안쪽 계층의 모델로 매핑하고 다시 반대 방향으로 매핑
    • 안쪽 계층은 자기의 모델만 알면 되고 매핑에 연연하지 않을 수 있다
  • 하지만 단점
    • 너무 많은 보일러플레이트 코드가 생긴다
      • 매핑 프레임워크를 사용하더라도 두 모델 간 매핑을 구현하기 꽤 번거롭다: 제네릭 코드나 리플렉션을 사용할 경우 매핑 로직을 디버깅하기도 힘들다
    • 도메인 모델이 계층 경계를 넘어서 통신하는 데 사용되고 있다
      • 인커밍/아웃고잉 포트에서 도메인 객체를 입력 파라미터와 반환값으로 사용한다

완전 매핑 전략

  • 각 연산이 전용 모델을 필요로 한다
    • 웹 어댑터와 애플리케이션 계층 각각이 자신의 전용 모델을 각 연산을 실행하는 데 필요한 모델로 매핑한다
  • 웹 계층은 입력을 애플리케이션 계층의 커맨드 객체로 매핑할 책임을 가진다
  • 각 유스케이스는 전용 필드와 유효성 검증 로직을 가진 전용 커맨드를 가진다
  • 그러고 나서 애플리케이션 계층은 커맨드 객체를 유스케이스에 따라 도메인 모델을 변경하기 위해 필요한 무엇인가로 매핑할 책임을 가진다
  • 한 계층을 다른 여러 개의 커맨드로 매핑하는 데는 하나의 웹 모델과 도메인 모델 간의 매핑보다 더 많은 코드가 필요하다
    • 하지만 이렇게 하면 여러 유스케이스의 요구사항을 함께 다뤄야 하는 매핑에 비해 구현하고 유지보수하기 훨씬 쉽다
  • 이 매핑 전략을 전역 패턴으로 추천하지는 않는다
    • 이 전략은 인커밍 어댑터와 애플리케이션 계층 사이에서 상태 변경 유스케이스의 경계를 명확히 할 때 가장 빛을 발한다
  • 애플리케이션 계층과 영속성 계층 사이에서는 매핑 오버헤드 때문에 사용하지 않는 것이 좋다

단방향 매핑 전략

  • 동일한 상태 인터페이스를 구현하는 도메인 모델과 어댑터 모델을 이용하면 각 계층은 다른 계층으로부터 온 객체를 단방향으로 매핑하기만 하면 된다
  • 즉 모든 계층의 모델들이 같은 인터페이스를 구현한다
    • 이 인터페이스는 관련 있는 속성에 대한 getter 메서드를 제공해서 도메인 모델의 상태를 캡슐화
  • 도메인 모델 자체는 풍부한 행동을 구현할 수 있고, 애플리케이션 계층 내의 서비스에서 이러한 행동에 접근할 수 있다
  • 도메인 객체를 바깥으로 전달하고 싶으면 매핑 없이 가능
    • 인커밍/아웃고잉 포트가 기대하는 대로 상태 인터페이스를 구현하고 있다
  • 바깥 계층에서는 상태 인터페이스를 이용할지 전용 모델로 매핑해야 할지 결정할 수 있다
    • 행동을 변경하는 것이 상태 인터페이스에 의해 노출돼 있지 않기 때문에 실수로 도메인 객체의 상태를 변경하는 일은 발생하지 않는다
  • 바깥 계층에서 애플리케이션 계층으로 전달하는 객체들도 이 상태 인터페이스를 구현하고 있다
    • 애플리케이션 계층에서는 이 객체를 실제 도메인 모델로 매핑해 도메인 모델의 행동에 접근 가능
    • 이 매핑은 factory라는 DDD 개념과 잘 어울린다
      • 팩토리는 특정한 상태로부터 도메인 객체를 재구성할 책임을 가지고 있다
  • 이 전략에서 매핑의 책임은 명확
    • 한 계층이 다른 계층으로부터 객체를 받으면 해당 계층에서 이용할 수 있도록 다른 무언가로 매핑하는 것
    • 각 계층은 한 방향으로만 매핑한다 -> 따라서 단방향 매핑 전략
  • 매핑이 계층을 넘나들며 퍼져있어서 다른 전략에 비해 개념적으로 어렵다
  • 계층 간의 모델이 비슷할 때 효과적
    • 읽기 전용 연산의 경우 상태 인터페이스가 필요한 모든 정보를 제공하기 때문에 웹 계층에서 전용 모델로 매핑할 필요가 전혀 없다

언제 어떤 매핑 전략을 사용할 것인가?

  • 답은 그때그때 다르다
  • 각 매핑 전략이 장단점을 가지고 있다
  • 같은 코드에 여러 패턴을 섞으면 어수선하게 느껴지긴 하지만 그런 이유로 최선의 패턴을 선택하지 않는 건 별로다
  • 언제 어떤 전략을 사용할지 결정하려면 팀 내에서 합의할 수 있는 가이드라인을 정해둬야 한다
    • 이 가이드라인은 어떤 상황에서 어떤 매핑 전략을 가장 먼저 택해야 하는가에 답할 수 있어야 한다

가이드라인

  1. 변경 유스케이스를 작업하고 있다면:
    • 웹 계층과 애플리케이션 계층 사이에서는 유스케이스 간의 결합을 제거하기 위해 완전 매핑 전략을 첫 번째 선택지로 해야 한다
      • 유스케이스별 유효성 검증 규칙이 명확해진다
      • 특정 유스케이스에서 필요하지 않은 필드를 다루지 않아도 된다
    • 애플리케이션 계층과 영속성 계층 사이에서는 매핑 오버헤드를 줄이고 빠르게 코드를 짜기 위해서 매핑하지 않기 전략을 첫 번째 선택지로 둔다
      • 애플리케이션 계층에서 영속성 문제를 다뤄야 하게 되면 양방향 매핑 전략으로 바꿔서 영속성 문제를 영속성 계층에 가둘 수 있게 한다
  2. 쿼리 작업을 한다면:
    • 매핑 오버헤드를 줄이고 빠르게 코드를 짜기 위해 매핑하지 않기 전략이 웹 계층과 애플리케이션 계층 사이, 애플리케이션 계층과 영속성 계층 사이에서 첫 번째 선택지가 되어야 한다
    • 애플리케이션 계층에서 영속성 문제나 웹 문제를 다뤄야 하게 되면 웹 계층과 애플리케이션 계층, 애플리케이션 계층과 영속성 계층 사이에서 각각 양방향 매핑 전략으로 바꿔야 한다
반응형
저작자표시 비영리 변경금지 (새창열림)
'Book' 카테고리의 다른 글
  • [Book] 만들면서 배우는 클린 아키텍처 - 1
덴마크초코우유
덴마크초코우유
IT, 알고리즘, 프로그래밍 언어, 자료구조 등 정리
    반응형
  • 덴마크초코우유
    이것저것끄적
    덴마크초코우유
  • 전체
    오늘
    어제
    • 분류 전체보기 (120)
      • Spring Framework (7)
        • Spring (3)
        • JPA (2)
        • Spring Security (0)
      • Language (51)
        • Java (11)
        • Python (10)
        • JavaScript (5)
        • NUXT (2)
        • C C++ (15)
        • PHP (8)
      • DB (16)
        • MySQL (10)
        • Reids (3)
        • Memcached (2)
      • 개발 (3)
      • 프로젝트 (2)
      • Book (2)
      • PS (15)
        • 기타 (2)
        • 백준 (2)
        • 프로그래머스 (10)
      • 딥러닝 (8)
        • CUDA (0)
        • Pytorch (0)
        • 모델 (0)
        • 컴퓨터 비전 (4)
        • OpenCV (1)
      • 기타 (16)
        • 디자인패턴 (2)
        • UnrealEngine (8)
        • ubuntu (1)
        • node.js (1)
        • 블로그 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Unreal
    웹
    map
    게임
    select
    알고리즘
    C++
    CPP
    PS
    게임 개발
    파이썬
    JavaScript
    자바
    memcached
    mscoco
    Unreal Engine
    Python
    클래스
    MySQL
    JS
    pytorch
    php
    블루프린트
    언리얼엔진4
    프로그래머스
    FPS
    redis
    딥러닝
    NUXT
    C
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
덴마크초코우유
[Book] 만들면서 배우는 클린 아키텍처 - 2
상단으로

티스토리툴바