最近我读了很多关于DDD的书。我有一些基本知识(并在实践中使用),但现在我决定去(几乎) 100%的DDD。当然,我马上就遇到了问题。
我为每个模块(特性)提供了3层:应用程序、域和基础设施。我使用六角结构模式,这基本上意味着我在域类中获得了我的核心逻辑,应用层使用它(但域层根本不知道应用层),基础结构实现了域端口(db存储库)和应用程序层的一些接口等等。
现在,当我在应用程序服务中处理一些用例时,我必须使用我的根聚合并执行一些逻辑,并最终将其映射到某些DTO以获得UI。问题是,要执行这样的映射,我必须为我的大多数属性提供getters/setter,这会使我丧命。我希望通过提供大量的业务方法而只提供很少的getter/setter来避免贫血模型。
我可以看到两种解决方案:
任何其他解决方案,你们如何处理这些常见的问题在您的应用程序?我知道在现实中很难做到purly,不遵守所有规则也没问题,但我注意到,尽可能少的getter/setter对我的设计有很大帮助,但同时DTO显然根本不属于域。
发布于 2018-09-17 18:29:01
问题是,要执行这样的映射,我必须为我的大多数属性提供getters/setter,这会使我丧命。
是的-我和它吵了很久。真正的答案是没有魔法。
如果您希望聚合有用,您需要能够以某种方式从其中获取信息。只编写数据库并不是很有趣;如果接口上没有可用的查询,那么从一开始就没有太多的意义将信息放入其中。
从聚合中获取值的特定域查询是可以接受的。关键限制
为了使代码看起来“更干净”,您可以做一些事情。
1)使用值对象对查询进行聚合响应,然后查询这些值对象以获取构建DTO所需的信息。
2)将工厂方法传递到聚合中,以获取所需的数据。
<T> T query(API<T> api)其中,API<T>是聚合可以与之交互的构建器/工厂。
3)有两个由聚合实现的独立接口(一个用于查询,一个用于命令),并且只允许调用方访问它们所需的接口。
4)有一个查询点,从聚合中获取“当前状态”,然后从它构建所有其他内容。
发布于 2018-09-19 06:40:29
Vaughn Vernon在“红皮书”第14章(应用程序)中,在“用户界面”一节(第512页)中阐述了一些备选方案:
希望能帮上忙。
发布于 2018-09-21 05:44:19
应用CQRS,您可以避免在AR中有getter。此外,您甚至可以将AR中的属性数量减少到只需要满足某些不变量的属性。
让我解释得更清楚些。
CQRS (命令查询责任分离)完全区分了应用程序提供的命令和查询操作。
命令操作通过执行某些用例来更改应用程序的状态。执行命令的结果是一个域事件,它包含更改的信息。
然后,域事件(建模为DTO)用于构建视图模型,该模型保存从查询返回的所有数据。视图模型是一个DTO,易于串行化并通过线路发送。
因此,您的查询操作(用于用info填充UI的操作)甚至不补充您的ARs。他们在您的视图模型上工作,因此对它的任何更改都不会对您的AR产生任何影响。
最后,正如我在开始时提到的,大多数情况下,我们的ARs中有大量的属性,只是为了将这些信息保存在数据库中。然而,这个信息从来没有被用来满足任何不变。例如,当我们保存用户名,但在任何其他用例中不再使用该数据时。如果信息已经在域事件中持久化,并在视图模型中被投影,那么您可以查询它,这样您就可以避免在AR中使用该字段,尽可能保持它们的干净。
https://stackoverflow.com/questions/52373148
复制相似问题