본문 바로가기

JAVA/DDD

DDD - 도메인 모델 패턴

반응형

DDD(Domain Driven Design) 도메인 주도 설계

도메인 모델 패턴

  • 일반적인 애플리케이션의 아키텍처는 4 개의 계층으로 구성

사용자인터페이스(UI) 또는 표현(Presentation)

  • 사용자의 요청을 처리하고 사용자에게 정보를 보여준다. 여기서 사용자는 소프트웨어을 사용하는 사람뿐아니라 외부 시스템도 사용자가 될수 있다.

응용(Application)

  • 사용자가 요청한 기능을 실행한다. 업무 로직을 직접 구현하지 않으며 도메인 계층으로 조합해서 기능을 실행한다.

도메인

  • 시스템이 제공할 도메인의 규칙을 구현한다.

인프라스트럭처(Infrastructure)

  • 데이터베이스나 메시징 시스템과 같은 외부 시스템과의 연동을 처리한다.

도메인 모델은 도메인 패턴을 의미한다(마틴 파울러)
도메인 모델은 아키텍처상의 도메인 계층을 객체 지향 기법으로 구현하는 패턴을 말한다.
도메인 계층은 도메인의 핵심규칙을 구현한다.

예) 주문 도메인의 경우'출고 전에 배송지를 변경할 수 있다는' 규칙과 '주문 취소는 배송전에만 할 수 있다'는 규칙을 구현한 코드가 도메인 게층에 위치하게 된다
이러한 도메인 규칙을 객체지향 기법으로 구현하는 패턴이 도메인 모델 패턴이다.

주문 도메인의 일부 기능을 도메인 모델 패턴으로 구현

public class Order { 
    private OrderState sate;     
    private ShippingInfo sippingInfo;           

    public void changeShippingInfo(ShippingInfo newShippingInfo) {       
        if(!state.isShippingChangeable()) {         
            throw new IllegalStateException("can't change shipping in" + state);       
        }       
        this.shippingInfo = newShippingInfo;     
    }           
    public void changeShipped() {       
        //로직검사       
        this.state = OrderState.SHIPPED;     
    }   
}         

public enum OrderState {     
    PAYMENT\_WAITING {       
        public boolean isShippingChangeable() {         
            return true;       
         }     
     },     
     PREPARING {       
         public boolean isShippingChangeable() {         
            return true;       
        }     
     },     
     SHIPPED, DELIVERING, DELIVERY\_COMPLETED;           
         public boolean isShippingChangeable(){       
            return false;     
     }   
}
  • 주문 상태를 표현하는 OrderState는 배송지를 변경할 수 있는지 여부를 검사 할수 있는 isShippingChangeable() 메서드를 제공한다.
  • 주문 대기중(PAYMENT_WAITING) 상태와 준비중(PREPARING)상태의 isShippigChangeable()메서드는 true를 리턴한다.
  • 즉 Orderstate는 주문 대기중이거나 상품준비중에는 배송지를 변경 할 수 있다는 도멘인 규칙을 구현하고 있다.
  • 실제 배송지 정보를 변경하는 Order 클래스의 changeShippingInfo()메서드는 OrderState의 isShippingChangeable() 메서드를 이용해서 변경 가능 여부를 확인한 후 변경 가능한 경우에만 배송지를 변경한다.
  • 큰틀에서 보면 OrderState는 Order에 속한 데이터이므로 배송지 정보 견경 가능 여부를 판단하는 코드를 Order로 이동할 수도 있다.
public class Order {     
    private OrderState sate;     
    private ShippingInfo sippingInfo;           

    public void changeShippingInfo(ShippingInfo newShippingInfo) {       
        if(!isShippingChangeable()) {         
            throw new IllegalStateException("can't change shipping in" + state);      
        }       
        this.shippingInfo = newShippingInfo;     
    }           
    private boolean isShippingChangeable(){
        return state == OrderState.PAYMENT_WAITING || state == OrderState.PREPARING;
    }
}     

public enum OrderState {
        PAYMENT\_WAITING, PREPARING, SHIPPED, DELIVERING, DELIVERY\_COMPLETED;
}
  • 배송지 변경이 가능한지 여부를 판단할 규칙이 주문상태와 다른 정보를 함께 사용한다면 배송지 변경가능 여부 판단을 OrderState만으로 할 수 없으므로 로직 구현을 Order에서 해야할 것이다.
  • 배송지 변경 가능 여부를 판단하는 기능이 Order에 있든, OrderState에 있든 중요한 점은 주문과 관련된 중요 업무 규칙을 주문 도메인 모델인 Order나 OrderState에서 구현한다는 점이다.
  • 핵심 규칙을 구현한 코드는 도메인 모델에만 위치하기 때문에 규칙이 바뀌거나 규칙을 확장해야 할 때 다른 코드에 영향을 덜 주고 변경 내역을 모델에만 반영 할 수 있게 된다.

 

DDD START! 도메인주도설꼐구현과 핵심개념 익히기 
저자-최범균

반응형

'JAVA > DDD' 카테고리의 다른 글

트랜잭션 범위  (0) 2017.12.23
Aggregate 애그리거트  (0) 2017.12.19
아키텍처  (0) 2017.12.18
엔티티와 밸류  (0) 2017.12.16
도메인 모델 도출  (0) 2017.12.15