Scala中的DDD:实体应该不可变吗?



在许多关于DDD的java教程中,实体是可变对象。

class Product {  
    private String status;
    public void prepare() {
       this.status = "Prepearing"; 
    } 
}

在上面的例子中,prepare方法改变了对象的内部状态。

但是在scala中,我希望我的实体是不可变的:

case class Product(status: String) {
    def prepare: Product = {
       this.copy(status = "Prepearing");
    }
}

所以我没有改变对象,而是返回一个新的实体。

在DDD方面有不可变实体和以上实现是可以的吗?

或者你能推荐一个更好的方法吗?

实体应该不可变吗?

是的,也许应该。如果我持有一个对象的引用,而你改变了它,我应该能看到这些改变。这就是我们使用实体而不是值的原因。

评论Vladimir Khorikov关于实体vs价值观的帖子;吉米伯加德;Martin Fowler…

或者你能推荐一个更好的方法吗?
为实体的状态创建一个单独的概念。让该状态为值对象。
class Product {  
    private State state;
    public void prepare() {
        this.state = this.state.updateStatus("Preparing"); 
    } 
}

Stuart Halloways关于Clojure时间模型的演讲有助于解释这里发生的事情;他的幻灯片31包含了一个很好的将身份可视化为一系列状态。

或者,您可以完全放弃OO方法,并将更改表示为纯函数

newState = theModel.prepare(oldState);

在DDD中,实体自然表现出不同的生命周期阶段或状态。在上面的例子中,产品状态可以是"准备"、"完成"、"发货"、"交付"等。由于这个生命周期,有时会有使用状态模式建模实体的倾向。一些DDD从业者强烈反对自由地使用实体的状态模式。原因是,它会导致实体方法的副作用。副作用会使代码更难测试,而且它们通常是bug的来源。上面的Product类必须能够显式地指定它需要操作的状态。它不能发布尚未准备和完成的东西

最新更新