주난v 개발 성장기

[DDD START!] 1장. 도메인 모델 시작 본문

개발 성장기/DDD

[DDD START!] 1장. 도메인 모델 시작

주난v 2020. 5. 6. 20:46

도메인

  • "서점" 도메인
  • 회원, 주문, 결제, 배송 하위 도메인 존재

도메인 모델 패턴

 

 

  • 사용자 인터페이스, 표현 계층
    • 사람, 외부 API 등 에게 요청을 받고, 정보를 보여줌
    • 사용자의 세션을 관리
  • 응용 계층
    • 비즈니스 로직 X
    • 각 도메인 계층에 업무를 위임하고, 이를 조합하여 실행
  • 도메인 계층
    • 비즈니스 로직
  • 인프라 스트럭쳐 계층
    • RDB
    • SQS, MQTT
    • API

Q ) 새로운 요구사항

  1. 출고 전에 배송지를 변경 할 수 있다.
  2. 주문 취소는 배송전에 할 수 있다.

이 2가지 요구사항을 각각 출고 서비스, 주문 서비스, 배송 서비스에서 구현을 해도 할 수는 있지만, 유지보수가 어렵고 

한 쪽에서 정책이 바뀐다면 모든 코드를 다 확인해야 한다.

 

public class Order {

	private OrderState state;
    
	private boolean isShippingChangeable() {
    	return state == OrderState.PAYMENT_WAITING || state == OrderState.WAITING;
    }
    
    private void cancel() {
    	...
    }
}

public enum OrderState {
	PAYMENT_WAITING, PREPARING, SHIPPED, DELIVERING, DELIVERING_COMPLETE;
}

 

// 주문 내역
public class OrderLine {
	
    private Product product;
    private int price;
    private int quantity;
    private int amounts;
    
    ....
}

public class ShippingInfo {
	private String receiverName;
    private String phoneNumber;
    ...

}

public class Order {
	private List<OrderLine> orderLine;
    private ShippingInfo shippingInfo;
    private int totalAmounts;
}

 

"도메인 관점에서 작성된 코드가 가독성이 높고, 문서로서 코드가 의미를 갖는다."

 


Entity와 Value

차이 ? 식별자 유무

Entity는 회원 - 회원 아이디, 주문 - 주문 아이디 등의 식별자를 가지며, 변경 되지 않는다. (PK)

Value - 데이터를 담는 객체, 불변 객체(immutable), 조합? 정도.. 주소 값


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

단순 값을 셋팅해주는 역할이라고 하더라도, completePayment() 등 처럼 명시적으로 선언을 한다.

Order order = new Order();
order.setOrderLine();
order.setShippingInfo();
order.setState();

위 처럼 구현을 한다면, 주문을 하는 쪽의 모든 코드를 고쳐줘야한다.

할인율이 추가되었다던지, 상태값이 추가 되었다던지...

접근 범위를 private으로 하고, 외부에서 데이터를 변경하는 용도로 set 메서드를 사용할 수 없다.


마치며...

도메인 용어를 명확하게 해라...

 

OrderState가 STEP1, STEP2...이렇다면 누구도 파악하기 힘들다.

시간을 들여 찾는 노력을 해야한다.