Orm DDD:存储库契约
我在不同的地方读到,DDD中的一个重要要求是对存储库有一个有约束的契约:Orm DDD:存储库契约,orm,domain-driven-design,repository,ddd-repositories,design-by-contract,Orm,Domain Driven Design,Repository,Ddd Repositories,Design By Contract,我在不同的地方读到,DDD中的一个重要要求是对存储库有一个有约束的契约: findByName(string name) findByEmail(string email) etc. 并且不提供通用查询接口: findBySpecification(Specification spec) 我确实理解为什么这很重要:能够模拟存储库进行测试,或者更改底层持久性框架 虽然这条规则在整个应用程序中并不难执行,但在为用户提供“高级搜索”表单时,我不知道如何执行它 比如说,我有一个表单,可以通过关键字、
findByName(string name)
findByEmail(string email)
etc.
并且不提供通用查询接口:
findBySpecification(Specification spec)
我确实理解为什么这很重要:能够模拟存储库进行测试,或者更改底层持久性框架
虽然这条规则在整个应用程序中并不难执行,但在为用户提供“高级搜索”表单时,我不知道如何执行它
比如说,我有一个表单,可以通过关键字、日期、作者等搜索博客帖子
这些标准是可以自由组合的,我显然不能为每个用例提供一种方法:
findByKeyword(string keyword)
findByDateRange(Date from, Date to)
findByKeywordAndDateRange(string keyword, Date from, Date to)
findByDateRangeAndAuthor(Date from, Date to, User author)
etc.
我是否遗漏了某些内容,或者这是该规则的例外情况之一?作为参数传递到存储库没有什么问题。这实际上是解决存储库接口上方法爆炸的一种非常好的方法。看看这个。”对于“高级搜索”场景,“过滤器”的名称可能比“规范”更合适。我认为该代码不会违反任何DDD指南:
Filter filter = new FilterBuilder()
.WithinDateRange(dateRange)
.IncludingKeywords("politics", "news")
.ByAuthor("John Smith")
.Build();
blogs.FindByFilter(filter);
请注意,创建筛选器的代码可以位于域之外。因为它不会违反任何域规则。如果有一条规则,比如“匿名作者发布的博客应该得到版主的批准”,该怎么办?虽然它可以用过滤器表示,但这样做会使业务逻辑的一部分外部化。将此规则放在域代码中,并有一个专用的存储库方法,如:
blogs.RequireModeratorAttention();
存储库模式有两个主要好处:
- 您可能希望使用持久性层测试应用程序层 (笑声)嘲笑
- 应用层是您关心的事情 因为这是商业逻辑