DDD

도메인(Domain) 모델에 지켜야할것!

Beekei 2021. 9. 15. 10:49
반응형

참조 투명성 관련 문제

public class OrderLine {
	private	Product product;
	private Money price;
	private int quantity;
	
	public OrderLine(Product product, Money price, int quantity) {
		this.product = product;
		this.price = price;
		this.quantity = quantity;
	}
}

Product product = new Product("티셔츠");
Money price = new Money(1000);
OrderLine line = new OrderLine(product, price, 2);

// OrderLine에 price값이 변경될 수 있다.
price.setValue(2000);
  • 위 코드 처럼 메소드에 값을 제공 후 변경할 경우 최종 결과값이 잘못 반영될 가능성이 있다.
  • 이런 문제가 발생하지 않도록 값을 제공 받을때 새로운 객체를 생성해 값을 주입해야한다.
public class OrderLine {
	private	Product product;
	private Money price;
	private int quantity;
	
	public OrderLine(Product product, Money price, int quantity) {
		this.product = new Product(product.getName()); // 새로운 객체
		this.price = new Money(price.getValue()); // 새로운 객체
		this.quantity = quantity;
	}
}

Product product = new Product("티셔츠");
Money price = new Money(1000);
OrderLine line = new OrderLine(product, price, 2);

// 새로운 객체로 주입되므로 OrderLine에 price값이 변경될 수 없다.
price.setValue(2000);

public 형식의 set 메서드 넣지 않기

  • 엔티티 객체에 public 형식에 set 메서드를 넣을 경우 외부에서 엔티티의 값을 변경할 수 있게 된다.
  • 최대한 set 메서드를 넣지 않거나 private로 설정해 엔티티 내부에서만 사용해야 한다.
public class OrderLine {
	private	Product product;
	private Money price;
	private int quantity;
	
	public OrderLine(Product product, Money price, int quantity) {
		setProduct(product);
		setPrice(price);
		setQuantity(quantity);
	}
	
	// 필수적인 값 검증을 위한 set 메서드
	private void setProduct(Product product) {
		if (product == null || product.getName() == null)
			throw new IllegalArgmentException("No Product");
		this.product = new Product(product.getName());
	}

	private void setPrice(Money price) {
		if (price == null || price.getValue() == null)
			throw new IllegalArgmentException("No Price");
		this.price = new Money(price.getValue());
	}

	private void setQuantity(int quantity) {
		if (quantity <= 0)
			throw new IllegalArgmentException("No Quantity");
		this.quantity = quantity;
	} 

}

해석 가능한 도메인 용어

public enum OrderState {
	STEP1, STEP2, STEP3, STEP4, STEP5
}
  • 많은 개발자들과 협업을 할때 위 코드 처럼 해석이 애매한 도메인 용어를 사용하면 커뮤니케이션을 통해 도메인 용어를 이해해야 한다.
  • 설계자 본인만 알 수 있는 도메인 용어가 아닌 모두가 코드를 보고 알 수 있는 도메인 용어를 사용해야 한다.
public enum OrderState {
	PAYMENT_WAITING, PREPARING, SHIPPED, DELIVERING, DELIVERY_COMPLETED
}
반응형