我一直在实践中使用这种实际的中等规模的单人项目(> 10万行Java),我发现了许多优点,主要是通过面向数据库的方法提供的灵活性和可重构性.我可以添加和删除域类,点击几个按钮,并将整个新的数据库模式和sql层推出.
但是,我经常面临的问题是,我发现很难调和富域的逻辑与sql数据库支持应用程序的事实.一般来说,这会导致典型的“1 N查询问题”,您可以在其中获取N个对象,然后对每个对象再次触发查询执行非平凡的方法.用手优化这一点可以让你在一个常量的SQL查询中执行这个过程.
在我的设计中,我允许系统插入这些优化的版本.我通过将代码移动到包含几十个特定于域的查询(例如getActiveUsers)的“查询模块”中,其中我有内存(天真而不可扩展)和基于sql(用于部署使用)实现.这使我能够优化热点,但有两个主要缺点:
>我有效地将我的一些域逻辑移动到不属于它的地方,实际上甚至将其推送到sql语句中.@H_404_9@>这个过程需要我仔细阅读查询日志,找出热点在哪里,之后我必须重构代码,通过将其降低为查询来降低其级别抽象.
有没有一个更好,更干净的方法来调和域驱动设计及其丰富的域模型,事实上,您不能将所有的实体都存储在内存中,因此被限制在数据库后端?
解决方法
第二种方法在我一直在使用DDD的时候更多的是我的焦点;如何使我的模型更加“可加载”,而不会牺牲太多的DDD优点.多年来我的假设一直以来,很多DDD模型都模拟了域概念,这些概念实际上是所有业务流程中所有允许的域状态的总和,以及随着时间的推移在每个业务流程中发生的不同状态.我认为,如果域模型在流程/状态方面稍微更标准化,那么很多这些加载问题会减少很多.这通常意味着没有“Order”对象,因为ordrer通常存在于具有相当不同的语义的多个不同状态中(ShoppingCartOrder,ShippedOrder,InvoicedOrder,HistoricalOrder).如果您尝试封装这是一个单一的Order对象,那么您总是会遇到很多加载/构造问题.
但这里没有银弹.