3

查看 DDD,我们将数据库抽象为我们操作的各种模型,并将其视为模型所在的存储库。然后我们在其上添加数据层和服务/业务层。我的问题是,在这样做的过程中,我们是否会通过构建胖模型而导致数据传输效率低下?

例如,假设我们有一个在屏幕上显示客户发票的系统。从 OOP 的角度考虑,我们最终可能会得到一个看起来像这样的对象:

class Invoice {
    Customer _customer;
    OrderItems _orderitems;
    ShippingInfo _shippingInfo;
}

class Customer {
    string name;
    int customerID;
    Address customerAddress;
    AccountingInfo accountingInfo;
    ShoppingHistory customerHistory;
}
    (for the sake of the question/argument, 
    let's say it was determined that the customer class had to 
    implement AccountingInfo and ShoppingHistory)

如果发票需要打印客户姓名,我们为什么要随身携带所有其他行李?使用存储库类型的方法似乎我们将构建这些需要所有这些资源(CPU、内存、复杂查询连接等)的复杂域对象,然后通过管道将其传输到客户端。

简单地将 customerName 属性添加到 invoice 类将脱离抽象,并且似乎是一种可怕的做法。另一方面,半填充像 Customer 这样的对象似乎是一个非常糟糕的主意,因为您最终可能会创建同一个对象的多个版本(例如,一个有地址但没有 ShoppingHistory 的一个,一个有 AccountingInfo 但没有地址等)。我错过了什么,或者不明白什么?

4

2 回答 2

1

由于良好的对象关系映射器可以延迟加载关系,因此您会为您的发票拉回客户,但忽略他们的会计和购物历史。如果您不使用对象关系映射器,您可以自己滚动。

通常你不能在你的客户端中这样做,因为你已经跨越了你的事务边界(结束了你的数据库事务),所以你的服务层来确保正确的数据已经被加载。

在服务层的单元测试中测试正确的数据(而不是太多)通常是好的。

于 2009-07-18T18:27:13.300 回答
0

您说“已确定客户类必须实现 AccountingInfo 和 ShoppingHistory”,因此清楚地显示发票并不是系统执行的唯一任务(否则如何“确定”客户需要其他功能?-) .

因此,无论如何您都需要一张客户表(用于其他功能)——当然,您的发票打印机需要从该表中获取客户数据(甚至只是名称),该表与系统中其他功能使用的相同。

所以“开销”纯粹是虚幻的——当你孤立地看待一个功能时,它似乎存在,但当你将整个系统视为一个集成的整体时,它根本不存在。

于 2009-07-18T18:14:25.820 回答