도메인이란 소프트웨어로 해결하고자 하는 문제 영역이다
ex)
public class Order {
private OrderState state;
private ShippingInfo shippinginfo;
public void changeShippingInfo(ShippingInfo newShippingInfo) {
if (!state.isShippingChangeable()) {
throw new IllegalStateException("can't change shipping in " + state);
}
this.shippinginfo = newShippingInfo;
}
...
}
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;
}
}
public class Order {
private OrderState state;
private ShippingInfo shippinginfo;
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;
}
주문 도메인과 관련된 몇가지 요구사항
위 요구사항을 통해 주문은 '출고 상태로 변경하기', '배송지 정보 변경하기', '주문 취소하기', '결제 완료하기' 기능을 제공한다는 사실을 도출할 수 있고, Order에 관련 기능을 메서드로 추가할 수 있다.
public class Order {
public void changeShipped() { ... }
public void changeShippingInfo(ShippingInfo newShippingInfo) { ... }
public void cancel() { ... }
public void completePayment() { ... }
}
엔티티의 식별자를 생성하는 시점은 도메인의 특징과 사용하는 기술에 따라 달라지는데, 보통 다음 중 한 가지 방식으로 생성한다
이렇게 setter를 쓰면 단순히 상태 값만 변경할 것인지 혹은 다른 처리를 위한 코드를 함께 구현할 것인지 애매해진다
ex) '결제 대기 중', '상품 준비 중', '출고 완료됨', '배송 중', '배송 완료됨', '주문 취소됨'이라는 주문 상태가 있는데 이를 코드 상에서 STEP1, STEP2, STEP3, STEP4, STEP5, STEP6이라는 Enum 상수로 표현되어있을 수 있다
이렇게 구현이 이루어져 있다면 개발자는 코드↔도메인 용어 해석 과정에서 어려움을 겪게 될 것이다
도메인 용어를 사용해서 PAYMENT_WATING, PREPARING, SHIPPED, DELIVERING, DELIVERY_COMPLETED라는 Enum 상수로 표현한다면 더욱 읽기 쉬운 코드가 될 것이다
에릭 에반스는 도메인 주도 설계에서 언어의 중요함을 강조하기 위해 유비쿼터스 언어(ubiquitous language)라는 용어를 사용했다
전문가, 관계자, 개발자가 도메인과 관련된 공통의 언어를 만들고 이를 대화, 문서, 도메인 모델, 코드, 테스트 등 모든 곳에서 같은 용어를 사용한다
시간이 지나 도메인에 대한 이해가 높아지면 새롭게 이해된 내용을 잘 표현할 수 있는 용어를 찾아내고 이를 다시 공통의 언어로 만들어 함께 사용한다
새로 발견한 용어는 코드나 문서에도 반영해서 산출물에 최신 모델을 적용한다