Domain Driven Design鼓励您使用丰富的域模型.这意味着所有域逻辑都位于域模型中,并且域模型是最重要的.持久性成为一个外部问题,因为域模型本身理想上不知道持久性(例如数据库).
我一直在实践中使用这个中型单人项目(超过100k的Java系列),我发现了许多优点,主要是它提供的灵活性和可重构性,而不是面向数据库的方法.我可以添加和删除域类,点击几个按钮,然后推出一个完整的新数据库模式和SQL层.
但是,我经常遇到一些问题,我发现很难将富域逻辑与支持应用程序的SQL数据库进行协调.通常,这会导致典型的"1 + N查询问题",您可以在其中获取N个对象,然后对每个再次触发查询的对象执行一个非平凡的方法.手动优化它允许您在恒定数量的SQL查询中执行该过程.
在我的设计中,我允许一个系统插入这些优化版本.我这样做是通过将代码移动到一个"查询模块",其中包含许多特定于域的查询(例如getActiveUsers),其中我都有内存(天真且不可扩展)和基于SQL(用于部署)的实现.这允许我优化热点,但有两个主要缺点:
我正在将我的一些域逻辑有效地移动到它不属于的地方,实际上甚至将它推入SQL语句中.
这个过程要求我仔细阅读查询日志以找出热点所在的位置,然后我必须重构代码,通过将其降低为查询来减少其级别抽象.
是否有一种更好,更清晰的方法来协调Domain-Driven-Design及其Rich Domain Model,因为您不能将所有实体都放在内存中,因此仅限于数据库后端?
有来看待这个问题至少有两个途径,一个是技术上的"我能做些什么来加载我的数据更聪明"的版本.我知道的唯一的真正智能的是,被部分地加载了加载点播休息,与零件的可能预载动态集合.JavaZone 2008上有一个有趣的话题
在我使用DDD的时候,第二种方法更像是我的关注点; 如何在不牺牲太多DDD优点的情况下使我的模型更加"可加载".我多年来的假设一直是很多DDD模型模型域概念实际上是所有允许畴状态的总和,跨随着时间的推移发生在每个业务流程的所有业务流程和不同的状态.我相信,如果域模型与流程/状态方面稍微标准化了很多这些加载问题得到非常降低.这通常意味着没有"订单"的对象,因为一个典型ordrer在具有相当不同的语义附接(ShoppingCartOrder,ShippedOrder,InvoicedOrder,HistoricalOrder)多个不同的状态存在.
但这里没有银弹......