胖域模型 => 效率低下?

发布于 2024-07-29 01:29:07 字数 938 浏览 6 评论 0原文

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

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

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 但没有地址等)。 我错过了什么,或者不明白什么?

Looking at DDD, we abstract the database into the various models which we operate on and look at it as a repository where our models live. Then we add the Data Layers and the Service/Business layers on top of it. My question is, in doing so, are we creating inefficiencies in data transfer by building fat models?

For example, say we have system that displays an invoice for a customer on the screen.
Thinking of it in terms of OOP, we'd probably end up with an object that looks somewhat like this:

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)

If the invoice solely needs to print the customer name, why would we carry all the other baggage with it? Using the repository type of approach seems like we would be building these complex domain objects which require all these resources (CPU, memory, complex query joins, etc) AND then transferring it over the tubes to the client.

Simply adding a customerName property to the invoice class would be breaking away from abstractions and seems like a horrible practice. On the third hand, half filling an object like the Customer seems like a very bad idea as you could end up creating multiple versions of the same object (e.g. one that has a an Address, but no ShoppingHistory, and one that has AccountingInfo but no Address, etc, etc). What am I missing, or not understanding?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薄荷梦 2024-08-05 01:29:07

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

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

在服务层的单元测试中测试正确的数据是否可用(但不要太多)通常是件好事。

As good object relational mappers can lazy load the relationships, you would therefore pull back the customer for your invoice, but ignore their accounting and shopping history. You could roll your own if you're not using an oject-relational mapper.

Often you can't do this within your client as you'll have crossed your trasaction boundary (ended your database trasaction) and so it is up to your service layer to ensure the right data has been loaded.

Testing the right data is available (and not too much of it) is often good to do in unit tests on a service layer.

温柔戏命师 2024-08-05 01:29:07

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

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

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

You say "it was determined that the customer class had to implement AccountingInfo and ShoppingHistory", so clearly displaying an invoice is NOT the only task that the system performs (how else was it "determined" that customers need those other functionalities otherwise?-).

So you need a table of customers anyway (for those other functionalities) -- and of course your invoice printer needs to get customer data (even just the name) from that one table, the same one that's used by other functionality in the system.

So the "overhead" is purely illusory -- it appears to exist when you look at one functionality in isolation, but doesn't exist at all when you look at the whole system as an integrated whole.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文