扩展富域模型

Wou*_*ens 11 domain-driven-design scalability model

Domain Driven Design鼓励您使用丰富的域模型.这意味着所有域逻辑都位于域模型中,并且域模型是最重要的.持久性成为一个外部问题,因为域模型本身理想上不知道持久性(例如数据库).

我一直在实践中使用这个中型单人项目(超过100k的Java系列),我发现了许多优点,主要是它提供的灵活性和可重构性,而不是面向数据库的方法.我可以添加和删除域类,点击几个按钮,然后推出一个完整的新数据库模式和SQL层.

但是,我经常遇到一些问题,我发现很难将富域逻辑与支持应用程序的SQL数据库进行协调.通常,这会导致典型的"1 + N查询问题",您可以在其中获取N个对象,然后对每个再次触发查询的对象执行一个非平凡的方法.手动优化它允许您在恒定数量的SQL查询中执行该过程.

在我的设计中,我允许一个系统插入这些优化版本.我这样做是通过将代码移动到一个"查询模块",其中包含许多特定于域的查询(例如getActiveUsers),其中我都有内存(天真且不可扩展)和基于SQL(用于部署)的实现.这允许我优化热点,但有两个主要缺点:

  • 我正在将我的一些域逻辑有效地移动到它不属于的地方,实际上甚至将它推入SQL语句中.
  • 这个过程要求我仔细阅读查询日志以找出热点所在的位置,然后我必须重构代码,通过将其降低为查询来减少其级别抽象.

是否有一种更好,更清晰的方法来协调Domain-Driven-Design及其Rich Domain Model,因为您不能将所有实体都放在内存中,因此仅限于数据库后端?

kro*_*old 5

有来看待这个问题至少有两个途径,一个是技术上的"我能做些什么来加载我的数据更聪明"的版本.我知道的唯一的真正智能的是,被部分地加载了加载点播休息,与零件的可能预载动态集合.JavaZone 2008上有一个有趣的话题

在我使用DDD的时候,第二种方法更像是我的关注点; 如何在不牺牲太多DDD优点的情况下使我的模型更加"可加载".我多年来的假设一直是很多DDD模型模型域概念实际上是所有允许畴状态的总和,跨随着时间的推移发生在每个业务流程的所有业务流程和不同的状态.我相信,如果域模型与流程/状态方面稍微标准化了很多这些加载问题得到非常降低.这通常意味着没有"订单"的对象,因为一个典型ordrer在具有相当不同的语义附接(ShoppingCartOrder,ShippedOrder,InvoicedOrder,HistoricalOrder)多个不同的状态存在.

但这里没有银弹......


Gre*_*ech 0

不,不是真的。无论如何,我并不知道(尽管我有兴趣听到 DDD 支持者的相反反应)。

根据我自己以及与我合作的经验丰富的团队的经验,如果您希望数据库支持的应用程序获得最佳性能,则将其架构转变为面向服务是不可避免的。我在这里写了更多相关内容(本文讨论了延迟加载属性,但您可以考虑将这一点应用于需要检索更多数据来完成其工作的类上的任何方法)。

正如您现在所做的那样,您可以从丰富的域模型开始,并在必要时出于性能原因将其转换为面向服务。只要您定义了绩效目标并且正在实现这些目标,就无需改变一切。我认为这是一个相当不错的务实方法。