单元测试纯领域驱动类

4
我希望创建一个基于纯领域驱动设计的系统。据我所知,这意味着我的领域对象应该有行为但没有形状。也就是说,它们不应该有任何getter或其他访问器。
与此同时,我正在尝试遵循TDD流程,并且在编写测试时遇到了一个障碍。
[Test]
public class new_purchase_order_should_have_purchase_ordernumber_of_1
{
     PurchaseOrder po = PurchaseOrder.CreatePurchaseOrder()
     Assert.AreEqual(1,po.PurchaseOrderNumber); 
}

public class PurchaseOrder
{
       private int _purchaseOrderNumber;
       static CreatePurchaseOrder()
       {
           _purchaseOrderNumber = SomeWayOfGettingAPONumber()
           //other initialisation
       }

        public int PurchaseOrderNumber {get { return _purchaseOrderNumber;}
}

如果不允许使用 getter,我该如何验证 CreatePurchaseOrder() 方法是否能够正确地执行并设置为 1 呢?
这对我来说是一个很大的概念障碍,尝试实现这个设计,希望能得到一些有用的建议。
谢谢。
2个回答

6
为什么领域对象不能有属性?你所谈论的纯行为只是静态方法,与领域对象没有任何关系。 wikipedia 告诉我们:
业务对象通常本身不做任何操作,但持有一组实例变量或属性(也称为属性),以及与其他业务对象的关联,编织表示业务关系的对象映射。一个业务对象没有行为的领域模型称为贫血领域模型。
因此,领域对象应该具有属性和(在大多数情况下)行为。 Martin Fowler说:
领域模型 - 领域的对象模型,包括行为和数据

1
我认为重点在于,虽然对象具有状态,但它们不会将其暴露出来:并非每个字段都有一个getter。这是良好的面向对象设计原则,适用于任何类型的对象。但这使得它们更难测试。 - Tom Anderson
6
“对象永不暴露状态”这个说法很令人困惑且是错误的。如果没有任何对象暴露状态,那么我们将拥有无声系统。这就使得它们一开始存在的意义荡然无存。 "没有状态"的概念不幸地出现了类似于传声筒的误解。面向对象编程状态的原则有两个:(1)“将接口与实现分离”,(2)“将数据与行为封装”。换句话说,(1) 不要向客户端暴露一个类的内部设计,但这并不意味着你不能暴露属性。(2) 不要建立无力的类。 - sfinnie

1

实现这一点的方法之一是遵循CQRS的思想。

CQRS在架构层面上将查询与行为分离(因此得名),并使用领域模型发布事件来公开状态。

但是,理解和正确实现它非常困难。特别是如果您没有先前使用领域驱动设计思想的经验。

因此,不要犹豫公开状态,只需确保它只能从对象本身进行修改即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接