【发布时间】:2013-01-22 12:16:58
【问题描述】:
我有一个简单的 实体 Order 伪代码:
class Order{
private int quantity;
private Date orderDate;
private Date shippingDate;
public Order(int quantity, Date orderDate, Date shippingDate){
if(quantity <= 0){ throw new Exception("Invalid quantity")}
if(shippingDate < orderDate){ throw new Exception("Invalid shippingDate")}
if(...more validation...){....throw Exceptions...}
//assign values if everything is OK
}
}
description、quantity、orderDate 和 shippingDate 都是从 Web 表单中读取的,每个表单都是由多个验证器配置的文本字段:
quantityField= new TextField('txt_quantity');
quantityFiled.addNotNullValidator().addNumaricValidator().addPositiveIntegerValidator()
如您所见,验证逻辑在 TextField 验证和实体验证之间重复。
我试图通过创建Quantity 类、OrderDate 类和ShippingDate 类来将值对象的概念引入我的实体。所以我的Order 实体变成了这样:
class Order{
private Quantity quantity;
private OrderDate orderDate;
private ShippingDate shippingDate;
public Order(Quantity quantity, OrderDate orderDate, ShippingDate shippingDate){
//assign values without validation I think??!!
}
}
例如 Quantity 类将是:
类数量{
private int quantity;
public Quantity(int quantity){
if(quantity <= 0){ throw new Exception("Invalid quantity")}
this.quantity=quantity;
}
}
现在问题:
- Aggregate Roots 不应该负责验证整个聚合吗?我的
Quantity班级不是违反了吗? - 如何在web表单验证中重用
Quantity的构造函数中的验证?我认为验证代码是重复的,所以我怎样才能验证一次或至少重用验证逻辑。 - 由于所有值对象都将验证自己,这是否意味着我不应该验证实体中的任何内容?
- 由于
ShippingDate依赖OrderDate进行验证,我应该如何验证发货日期? - DDD 工厂适合所有这些吗?
【问题讨论】:
-
你说你有一个实体
Customer,但你显示的是Order的代码。 -
@DanielHilgarth 对不起我的错误。我现在修好了。
-
在值对象之外重用验证很简单。将验证逻辑提取到返回 bool 的静态方法。如果返回 false,构造函数将调用该方法并抛出。 web层可以问Quantity.IsValid(value)
-
如前所述,您的问题不在于拥有或不拥有对象值。不必要地添加它们不会使事情变得更容易。您需要区分两种类型的检查:1)检查是否应用了域级约束。 2) 检查用户输入,网络级验证。
标签: oop language-agnostic domain-driven-design