在这个关于域驱动设计的伟大book中,一章专门介绍用户界面及其与域对象的关系。
令我困惑的一点是用例最优查询和演示者之间的比较。
处理最佳查询的摘录(第517页)是:
而不是读取各种各样的整个聚合实例 类型,然后以编程方式将它们组合成一个容器 (DTO或DPO),您可能会使用所谓的最佳用例 查询。
这是您使用finder查询设计存储库的地方 将自定义对象组成一个或多个超集的方法 聚合实例。
查询动态地将结果放入a Value Object(6)专门用于满足使用需求 情况。
您设计了一个值对象,而不是DTO,因为查询是 特定于域,而不是特定于应用程序(与DTO一样)。习俗 用例最佳值对象然后由视图直接使用 渲染器。
因此,最佳查询的好处是直接提供特定视图值对象,充当真实视图模型。
稍后页面描述了演示者模式:
演示模型充当适配器。它掩盖了细节 域模型通过提供设计的属性和行为 就观点的需要而言。
而不是要求 域模型专门支持必要的视图属性,它 演示模型的责任是推导出 来自域的状态的特定于视图的指示符和属性 模型。
听起来两种方式都可以构建特定于用例的视图模型。
目前我的调用链(使用Play Framework)如下所示:
对于查询:控制器(充当发送Json的Rest接口) - >查询(通过最佳查询返回特定值对象)
对于命令:控制器(充当发送Json的Rest接口) - >应用服务(命令) - >域服务/存储库/聚合(应用程序服务返回无效)
我的问题是:如果我已经练习了用例最优查询,那么实现presenter模式有什么好处?如果可以总是使用最佳查询来直接满足客户需求,为什么还要使用演示者呢?
我只想到演示者模式的一个好处:处理命令而不是查询,从而提供命令对应于演示者确定的视图模型的一些域对象。然后,控制器将与域对象分离。 实际上,Presenter描述的另一个摘录是:
此外,用户执行的编辑也会被跟踪 演示模型。
这不是放置重载的情况 对演示模型的责任,因为它意味着适应 在两个方向上,模型可以查看和查看模型。
但是,我更喜欢将纯原语发送到应用程序服务(命令),而不是直接处理域对象,所以这个好处不适用于我。
有什么解释吗?
答案 0 :(得分: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)));
但最佳查询是面向视图的(每个视图的查询)。我认为这两个解决方案是针对 none-cqrs 风格的ddd架构而设计的。由于查询不是基于存储库而是基于特定的瘦数据层,因此不再需要cqrs样式的结构。