代码之家  ›  专栏  ›  技术社区  ›  MunkiPhD

胖域模型=>低效?

  •  3
  • MunkiPhD  · 技术社区  · 16 年前

    查看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类将脱离抽象,这似乎是一种可怕的实践。第三方面,像客户这样填充一个对象的一半看起来是一个非常糟糕的主意,因为您最终可能会创建同一对象的多个版本(例如,一个具有地址,但没有购物历史,以及一个具有accountinginfo但没有地址等)。我错过了什么,还是不理解?

    2 回复  |  直到 16 年前
        1
  •  1
  •   RichH    16 年前

    由于好的对象关系映射器可以懒惰地加载关系,因此您将收回客户的发票,但忽略他们的记帐和购物历史记录。如果不使用项目关系映射器,可以自己滚动。

    通常情况下,您不能在客户机内执行此操作,因为您将跨越事务边界(结束数据库事务),因此由您的服务层来确保加载了正确的数据。

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

        2
  •  0
  •   Alex Martelli    16 年前

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

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

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

    推荐文章