Post

1. 도메인모델시작하기

1. 도메인모델시작하기의 핵심 개념과 실무 포인트를 정리한 학습 노트입니다.

1. 도메인모델시작하기

한눈에 보기

  • 도메인이란 ?
  • 도메인은 도메인, 하위 도메인으로 나눌 수 있다.
  • 온라인 서점(도메인), 온라인 서점은 서점을 운영하기 위한 결제, 주문, 배송, 상품 이라는 하위 도메인을 갖는다.

도메인이란 ?

  • 도메인은 도메인, 하위 도메인으로 나눌 수 있다.
  • 온라인 서점(도메인), 온라인 서점은 서점을 운영하기 위한 결제, 주문, 배송, 상품 이라는 하위 도메인을 갖는다.
  • 내가 공부했을 때 도메인이란 ? 업무다.
  • 현실적으로 회사들은 모든 하위 도메인을 구축하진 않는다. 배송을 위해 외부 배송업체 시스템을 연동하거나, 결제 대행사를 연동하거나 하는 것처럼.

도메인 전문가

  • 도메인 전문가는 현업 전문가 라고도 볼 수 있을 것 같다.
  • 회계처리를 위한 회계사, 정산담당자와 같은 사람들.
  • 개발자는 도메인 전문가 + 기획자와 소통하여 이들이 사용하기를 원하는 기능을 요구사항을 토대로 개발하게된다.
  • 요구사항을 좀 더 깊게 이해하기 위해서는 도메인 전문가와 직접 소통하는 것이 효율적이다.
    • 중간에 도메인 전문가의 요청이 잘못 전달되거나, 뉘앙스가 잘못 전달될 수 있기 때문.
  • 도메인 전문가 뿐만 아니라 소프트웨어 제품을 만드는데 참여하는 모든 이해관계자들이 같은 수준의 도메인 지식을 갖추는게 이상적이다.
  • 소프트웨어를 개발하는동안 협업하는 모든 구성원들은 해당 도메인을 더 잘 이해하게된다.
    • 프로젝트 초기에 완벽하게 도메인을 완성하는 것을 불가능하다.
    • 구성원 모두가 도메인 전문가와 함께 도메인에 대한 기반지식을 천천히 다져가면서 점진적으로 발전시켜 나가야한다.

도메인 모델

  • 특정 도메인을 개념적으로 표현한 것.
  • 다이어그램, UML 등 특정 업무에 대한 흐름, 상태, 조건 등을 사람들이 알기 쉽게 도식화 한 것.
  • 도메인을 이해하는데에 도움이 된다면 표현 방식이 무엇인지는 중요하지 않다.
  • 도메인에 따라 용어 의미가 달라질 수 있으므로 되도록이면 여러 하위 도메인을 하나의 다이어그램에 모델링하지 말자.
    • 이부분은 유비쿼터스언어를 학습하며 다시 이해하는게 좋을듯.

도메인 모델 패턴 (계층구조 설명)

  • 아키텍쳐 구성
    • UI (사용자 인터페이스 ) layer : 사용자의 요청을 처리하고 사용자에게 정보를 보여준다. 사용자는 소프트웨어 실제 사용자 뿐만 아니라, 외부 시스템일 수도 있다.
    • Application (응용) layer : 사용자가 요청한 기능을 실행한다. 비즈니스 로직을 직접 구현하지 않고, 도메인 계층을 조합해서 기능을 실행한다.
    • Domain layer : 도메인의 핵심 규칙을 구현한다.
      • 실제 업무 규칙(비즈니스 로직)을 구현한다.
    • Infrastructure layer : DB, Kafka, MQ, 외부 API 등과 같은 외부 시스템과의 연동을 처리한다.
  • 도메인 모델은 아키텍처상의 도메인 계층을 객체지향 기법으로 구현하는 패턴을 말한다.
  • 주문과 관련된 업무 규칙을 주문 도메인에 구현해두고 사용하게되면 규칙이 바뀌거나 규칙을 확장해야할 때 다른 코드에 영향을 덜 주고 변경 내역을 모델에 반영할 수 있게된다.

코드의 문서화

  • 실제 개발자들은 코드를 보며 도메인을 깊게 이해하게 되므로 코드 자체도 문서화의 대상이 된다.
  • 도메인 지식이 잘 묻어나도록 코드를 작성하지 않으면 코드의 동작 과정은 해석할 수 있어도 도메인 관점에서 왜 그렇게 코드를 작성했는지 이해하는데에는 도움이 되지 않고, 오히려 분석하는 시간이 오래걸린다.
  • 단순히 코드를 보기좋게 작성하는 것 뿐만아니라 도메인 관점에서 코드가 도메인을 잘 표현해야 비로소 코드의 가독성이 높아지고 문서로서 코드가 의미를 갖는다.

Entity, Value

  • Entity
    • 도메인을 도출한 모델은 크게 엔티티, 밸류로 구분할 수 있다.
    • 엔티티는 Identifier(식별자)를 갖는다.
    • 식별자는 여러 속성을 결합한 비즈니스 식별자일수도, DB 시퀀스일수도, UUID일수도 있다.
    • 주문에서 배송지 주소가 바뀌거나 상태가 바뀌더라도 식별자인 주문번호가 바뀌지 않는 것처럼, 엔티티의 식별자는 바뀌지 않는다.
    • 엔티티끼리 식별자가 같으면 같은 엔티티라고 판단할 수 있다. java의 경우 실제 구현단계에서 equals(), hashCode() 를 구현하여 엔티티 객체가 같음을 알게 할 수 있다.
  • Value
    • 밸류 타입은 식별자를 포함하지 않고 속성데이터만 포함한다.
    • 개념적으로 완전한 하나를 표현할 때 사용한다.
    • 파편화된 데이터를 묶어 쉽게 하나의 개념으로 표현할 수 있다.
      • Address는 address1, address2, zipCode 3개의 데이터를 묵은 데이터 타입이다.
    • 밸류 타입을 위한 기능을 추가할 수 있다.
      • 값을 불변하게 설계.
      • 예를들어 Money 라는 타입을 만들었다고 가정할 경우 돈 계산에 특화된 기능으로 구현 가능.

엔티티 식별자와 밸류타입

  • 엔티티 식별자는 단순히 변수명으로 표현하는 것 보다 때로는 밸류 타입으로 의미가 더 잘 들어나게 할 수 있다.
  • 사람마다 생각이 다르니까 id 라는 변수명만 보고는 어떤 id인지 모를 수도 있다. ```java

// 개선 전 public class Order { private String id;

1
... 생략 }

// 개선 후 public class Order { private OderNo id;

1
... 생략 } ```

도메인 모델에 set 메서드 남용하지 않기.

  • set 메서드는 도메인의 핵심 개념이나 의도를 코드에서 사라지게 한다.
  • completePayment() , setOrderState() 두개 메서드 명칭은
    • completePayment() 의 경우 결제를 완료했다는 의미를 표시하고 있는 반면
    • setOrderState() 의 경우 단순히 결제 상태를 변경하는 듯한 의미를 내보이고 있다.
  • set 메서드는 필드값만 변경하고 끝나기때문에 상태변경과 관련된 도메인 지식이 코드에서 사라지게된다.
  • set 메서드는 필드값 변경을 통해 객체를 생성할 때 온전하지 않은 상태를 만들 수 있다.

    1
    2
    3
    4
    5
    6
    
      Order order = new Order();
      order.setOrderLine(lines);
      order.setShippingInfo(shippingInfo);
    
      // 주문자 정보를 입력하지 않은 상태에서 주문처리 완료 처리를 하게되는 꼴
      order.setState(OrderState.PREPARING);
    
  • Order 도메인 객체가 불완전한 상태로 사용되는 것을 막으려면 생성 시점에 생성자를 통해 필수 데이터를 강제할 수 있다.

    1
    
      Order order = new Order(주문정보, 주문서, 배송지정보, 주문완료상태);
    
  • 생성자를 통해 생성할 때 데이터 검증을 하게하도록 한다면, 생성이후 시점부터는 주문하는데에 문제 없는 완전한 Order 객체를 보장시켜줄 수 있다.

도메인 용어와 유비쿼터스 언어

  • Ubiquitous : 어디에나 있는.
  • 코드를 작성할 때 도메인에서 사용하는 용어를 사용하는 것은 매우 중요하다.
  • 용어를 코드에 반영하지 않으면 개발자는 업무 회의시 오고가는 용어를 한번 더 번역해서 코드에 반영해야 한다.
  • 최대한 도메인 용어를 사용해서 도메인 규칙을 코드로 작성하여 가독성을 증가시킬 수 있다.
  • 전문가, 관계자, 개발자, 기획자 등등 도메인과 관련된 모든 사람들이 공통의 언어를 만들고 이를 대화, 문서, 코드, 모델, 테스트 등의 모든 영역에서 사용하면 소통과정에서 발생하는 용어의 모호함을 줄일 수 있고 개발자는 도메인과 코드 사이에서 불필요한 해석 과정을 줄일 수 있다.
  • 출고 라는 단어를 생각해보면 각자 이런 생각을 할 수 있다.
    • 뭔가 출발했나보다
    • 물류센터에서 출고했겠지
    • 출고가 뭐지?
  • 모두가 같이 고민해서 공통의 언어를 도출해 낸다면 우리 업무영역에서는 앞으로 출고 라는 단어에서 발생하는 혼선을 없을 것이다.
    • 출고 라는 단어는 우리 도메인에서는 앞으로 배송출발 (물류센터에서 상품이 배송지로 출발하는 것) 이라고 정의합시다 ! “
  • 그러나 다른 업무영역에서는 여전히 출고라는 단어를 고수할 수도 있다.
This post is licensed under CC BY 4.0 by the author.