DDD Start Chapter1 요약

'온라인 서점' 이라는 소프트웨어를 개발하는 것으로 가정한다.

도메인

  • 개발자 입장에서 '온라인 서점'은 구현 대상이 된다.
  • 온라인 서점 소프트웨어는 상품조회, 구매, 결제, 배송 추적 등의 기능을 제공해야 한다.
  • '온라인 서점'은 소프트웨어로 해결하고자 하는 문제 영역, 즉 도메인(Domain)에 해당 한다.
  • 한 도메인은 몇 개의 하위 도메인으로 나눌 수 있다.

도메인 모델

  • 특정 도메인을 개념적으로 표현한 것이다.
  • 도메인 자체를 이해하기 위한 개념 모델이다.
  • 도메인 모델 표현 방법
    • 객체를 이용한 도메인 모델은 기능과 데이터를 함께 보여주는 객체 모델 (클래스 다이어그램)
    • 상태 다이어그램
    • 도메인을 이해하는데 도움이 된다면 표현방식은 중요하지 않다.

도메인 모델 패턴

[표] 아키텍처 구성

계층(Layer)설명
사용자인터페이스(UI)사용자의 요청을 처리하고 사용자에게 정보를 보여준다. 사용자는 사람뿐만 아니라 외부 시스템도 사용자가 될 수 있다.
응용(Application)사용자가 요청한 기능을 실행한다. 업무 로직을 직접 구현하지 않으며 도메인 계층을 조합해서 기능을 실행한다.
도메인시스템이 제공할 도메인의 규칙을 구현한다.
인프라스트럭처(Infrastructure)데이터베이스나 메시징 시스템과 같은 외부 시스템과의 연동을 처리한다.
  • 아키텍처상의 도메인 계층을 객체 지향 기법으로 구현하는 패턴을 말한다.
  • 도메인 계층은 도메인의 핵심 규칙을 구현한다.
  • 핵심 규칙을 구현한 코드는 도메인 모델에만 위치하기 때문에 규칙이 바뀌거나 규칙을 확장 할 때 다른 코드에 영향을 덜 주고 변경 내역을 모델에 반영할 수 있게 된다.

엔티티와 밸류

도메인 모델은 엔티티(Entity)와 밸류(Value)로 구분할 수 있다.

엔티티

  • 엔티티는 고유한 식별자를 갖는다.
  • 엔티티의 식별자는 고유하기 때문에 두 엔티티의 식별자가 같으면 두 엔티티는 같다고 표현할 수 있다. 엔티티 클래스는 식별자를 이용해서 equals() 메서드와 hashCode() 메서드를 구현할 수 있다.

엔티티 식별자 생성

  • 특정 규칙에 따라 생성
  • UUID 생성
  • 값을 직접 입력
  • 일련번호 사용(시퀀스나 DB의 자동 증가 컬럼 사용)

밸류 타입

public class ShippingInfo {
	
    private String receiverName; // 개념적으로 받는 사람 정보
    private String receiverPhoneNumber; // 개념적으로 받는 사람 정보
}
  • ShippingInfo 클래스의 receiverName 필드와 receiverPhoneNumber 필드는 서로 다른 두 데이터를 담고 있지만 개념적으로 받는 사람을 의미한다.
  • 두 필드는 실제로 한 개의 개념을 표현하고 있다.
  • 밸류 타입은 개념적으로 완전한 하나를 표현할 때 사용한다.
  • 꼭 두 개 이상의 데이터를 가져야 하는 건 아니다.
  • 또 다른 장점은 밸류 타입을 위한 기능을 추가할 수 있다.
  • 밸류 객체의 데이터를 변경할 때는 변경한 데이터를 갖는 새로운 밸류 객체를 생성하는 방식을 선호 한다.

엔티티 식별자

  • 주문번호의 경우 OrderNo 대신 String 타입을 사용한다면 'id' 라는 변수명만으로는 해당 필드가 주문 번호인지 알 수 없다.
  • 필드 의미가 드러나도록 하려면 'id' 라는 필드 이름대신 'orderNo' 라는 필드 이름을 사용해야 한다.
  • 반면에, 식별자를 위해 OrderNo 타입을 만들면 타입 자체로 주문번호라는 것을 알 수 있으므로 필드 이름이 'id' 여도 실제 의미를 찾는 것은 어렵지 않다.

도메인 모델에 set 메서드 넣지 않기

  • set 메서드는 도메인의 핵심 개념이나 의도를 코드에서 사라지게 한다.
  • completePayment()는 결제 완료와 관련된 처리 코드를 함께 구현하여 도메인 지식을 코드로 구현하는 것이 자연스럽다.
  • set 메서드는 단순히 상태 값만 변경할지 아니면 상태 값에 따라 다른 처리를 위한 코드를 함께 구현할지 애매하다.
  • 도메인 객체를 생성할 때 완전한 상태가 아닐 수도 있다. 아래 코드는 주문자를 설정하는 것을 누락하고 있다.
// set메서드로로 데이터를 전달하도록 구현하면
// 처음 order를 생성하는 시점에 order는 완전하지 않다.
Order order = new Order();

// set 메서드로 필요한 모든 값을 전달해야 함
order.setOrderLine(lines);
order.setShippingInfo(shippingInfo);

// 주문자(Orderer)를 설정하지 않은 상태에서 주문 완료 처리
order.setState(OrderState.PREPARING);
  • 도메인 객체가 불완전한 상태로 사용되는 것을 막으려면 생성자를 통해 필요한 데이터를 모두 받아야 한다.
Order order = new Order(orderer, lines, shippingInfo, OrderState.PREPARING);
  • 생성자로 필요한 정보를 모두 받으므로 생성자를 호출하는 시점에 데이터가 올바른지 검사할 수 있다.

좋은 웹페이지 즐겨찾기