3

在这关于领域驱动设计的好书中,有一章专门介绍用户界面及其与领域对象的关系。

让我感到困惑的一点是用例优化查询和演示者之间的比较。

处理最佳查询的摘录(第 517 页)是:

与其读取多个不同类型的完整聚合实例,然后以编程方式将它们组合到单个容器(DTO 或 DPO)中,不如使用所谓的用例优化查询。
这是您使用查找器查询方法设计存储库的地方,这些查找器查询方法将自定义对象组合为一个或多个聚合实例的超集。
查询动态地将结果放入一个值对象 (6) 中,该值对象专门设计用于满足用例的需求。
您设计的是值对象,而不是 DTO,因为查询是特定于域的,而不是特定于应用程序的(DTO 也是如此)。然后,视图渲染器直接使用自定义用例最佳值对象。

因此,优化查询的好处是直接提供特定于视图的值对象,充当真实视图模型。

稍后一页,介绍者模式被描述:

表示模型充当适配器。它通过提供根据视图需求设计的属性和行为来掩盖域模型的细节。
不是要求域模型专门支持必要的视图属性,而是表示模型的责任是从域模型的状态中派生视图特定的指示符和属性。

听起来这两种方式都实现了特定于用例的视图模型的构建。

目前我的调用链(使用 Play Framework)看起来像:

对于查询:控制器(充当发送 Json 的 Rest 接口)-> 查询(通过优化查询返回特定值对象)

对于命令:控制器(充当发送 Json 的 Rest 接口)-> 应用程序服务(命令)-> 域服务/存储库/聚合(应用程序服务返回 void)

我的问题是:如果我已经练习了用例优化查询,那么实现演示者模式有什么好处?如果一个人总是可以使用最佳查询来直接满足客户的需求,那为什么还要打扰演示者呢?

我只是想到了演示者模式的一个好处:处理命令,而不是查询,从而提供命令一些与演示者确定的视图模型相对应的域对象。然后控制器将与域对象分离。事实上,Presenter 描述的另一个摘录是:

此外,用户执行的编辑由演示模型跟踪。
这不是在表示模型上放置重载职责的情况,因为它意味着适应两个方向,模型到视图和视图到模型。

但是,我更喜欢将纯原语发送到应用程序服务(命令),而不是直接处理域对象,所以这个好处不适用于我。
有什么解释吗?

4

1 回答 1

2

只是一个猜测:)

preseneter 模式可以尽可能地重用存储库的聚合查找器方法。例如,我们有两个视图,在这种情况下我们需要两个适配器(每个视图一个适配器),但我们只需要一个存储库查找方法:

class CommentBriefViewAdapter {
    private Comment comment;

    public String getTitle() {
         return partOf(comment.getTitle()); 
         //return first 10 characters of the title, hide the rest
    } 
    .....//other fields to display
}

class CommentDetailViewAdapter {
    private Comment comment;

    public String getTitle() {
         return comment.getTitle();//return full title
    } 
    .....//other fields to display
}

//In controller:
model.addAttribute(new CommentBriefViewAdapter(commentRepo.findBy(commentId)));
// same repo method
model.addAttribute(new CommentDetailViewAdapter(commentRepo.findBy(commentId)));

但最佳查询是面向视图的(每个视图一个查询)。我认为这两个解决方案是为非 cqrs风格的 ddd 架构设计的。在 cqrs 风格的架构中不再需要它们,因为查询不是基于存储库而是基于特定的瘦数据层。

于 2013-12-27T18:07:11.980 回答