在许多关于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方面是否可以使用不可变实体和上面的实现?
或者你能推荐一种更好的方法吗?
答案 0 :(得分:1)
在DDD中,实体自然地表现出不同的生命周期阶段或状态。在上面的示例中,产品状态可以是“准备”,“实现”,“运输”,“交付时”等。由于此生命周期,有时会使用状态模式对实体进行建模。一些DDD从业者强烈反对对实体自由使用国家模式。原因是,它可能导致实体方法的副作用。副作用可能使代码更难测试,它们通常可能是错误的来源。上面的Product类必须能够明确指定它需要操作的状态。它无法运送尚未准备和实现的东西。
答案 1 :(得分:1)
实体应该是不可变的吗?
是的,可能应该。如果我持有对象的引用,并且你更改它,我应该看到这些更改。这几乎是我们使用实体而不是价值的原因。
回顾弗拉基米尔·霍里科夫关于entities vs values的帖子; Jimmy Bogard; Martin Fowler ....
或者你能推荐一种更好的方法吗?
为实体的州创建单独的概念。让该状态成为价值对象。
class Product {
private State state;
public void prepare() {
this.state = this.state.updateStatus("Preparing");
}
}
Stuart Halloways关于Clojure time model的谈话有助于解释这里发生的事情;他的deck中的幻灯片31包含了身份连续状态的良好可视化。
或者,您可以完全放弃OO方法,并将更改表示为纯函数
newState = theModel.prepare(oldState);