【问题标题】:Fat Domain Models => Inefficient?胖域模型 => 低效?
【发布时间】:2009-07-18 17:36:44
【问题描述】:

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

【问题讨论】:

    标签: performance repository design-patterns data-transfer


    【解决方案1】:

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

    通常您无法在客户端中执行此操作,因为您已经跨越了事务边界(结束了数据库事务),因此由您的服务层来确保已加载正确的数据。

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

    【讨论】:

    • 好点。我想我一定没有完全理解延迟加载>.
    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2011-04-14
      • 1970-01-01
      • 2018-07-21
      • 2012-01-25
      • 1970-01-01
      • 1970-01-01
      • 2019-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多