因此,当我们谈论过滤和查询时,我正在努力应对DDD必须遵循的方法.从这个问题 Is it okay to bypass the repository pattern for complex queries?我可以看到用户的过滤应该在获得所有产品后完成.接受的
Products products = /* get Products repository implementation */; IList<Product> res = products.BoughtByUser(User user);
但等等,如果数据库有100万个产品?不是直接在数据库中执行此过滤器的最佳方法,如下所示:
productsRepository.Find(p => p.User.Id == userId);
但是根据我对DDD的实际了解,这是错误的,因为这个逻辑应该在产品本身内部.
因此,如何处理这种情况?
我同意Yorro的回答.根据评论,产品确实是一个存储库.可以进一步探讨围绕基础数据结构的性能与在应用程序中保持领域知识的问题.
数据库非常适合过滤和查询数据,它们经过优化可以做到这一点,而我们忽略这一点只是为了“保持我们在域中的知识”是天真的.
您的示例显示了Repository Specialization,虽然详细,但它很好.
该搜索的逻辑由该调用封装,只要用于调用该方法的接口在域中,并且在数据层中实现,一切都很好.
实际上,调用可以是执行非常复杂操作的存储过程. (在这种情况下,是的,你的一些逻辑已经逃脱了域,但你做出了有意识的决定,如果你引入另一种数据技术,你将不得不再次实现该功能.)
还有另一种选择……
我们可以在规范(http://en.wikipedia.org/wiki/Specification_pattern)中封装搜索的逻辑,并将规范从我们的域逻辑代码传递给我们的Repository,后者将解释规范并执行查询.
这使得我们的域名无视基础数据结构的工作方式,但它使其能够控制搜索条件.
我通常发现自己实现了Repository Specialization的混合,并且拥有一个基础存储库,可以接受更轻量级查询的ISpecification.