kab*_*ros 6 c# ooad domain-driven-design ddd-repositories
我已经研究了几个试图遵循DDD原则的应用程序,我注意到我们最终遇到了服务层和感觉像代码味道的存储库之间存在重复的情况.
对于服务层中的大多数操作,它似乎是直接映射到CRUD操作,GetAll,GetById,创建,删除等.架构流程在这些行中:我有一个控制器调用服务层调用一个调用ORM的Repository,它与后端进行通信.
因此,例如GetAll将存在于SL和Repository中.现在,如果我们有一个变更/业务要求,GetAll应该忽略某些项目,我应该怎么做,我应该忽略存储库中的这些,还是应该进入服务层的业务逻辑?如果我们只是让服务层直接调用ORM,那么生活会不会更容易?
总结一下:我理解服务层可以抽象一些业务逻辑,但是在大多数情况下 - 它处理简单的CRUD操作,是不是更容易摆脱存储库?但是,如果SL 还包含一些具有复杂业务逻辑的方法,那么它们应该通过存储库吗?从良好的设计角度来看,我是否应该支持一致性并始终通过存储库或只是保持简单,只使用存储库,而不是简单的一对一映射到CRUD操作.
PS:我发现似乎有类似的问题,但没有找到任何令人满意的答案
在大多数情况下 - 它正在处理简单的CRUD操作,不会更容易摆脱存储库
恕我直言,我不会说要摆脱存储库.我会说,如果你在做CRUD,你根本不需要DDD.如果您阅读Fowler的企业模式或Evans,他们都会说只有当您的域逻辑非常复杂时才使用DDD.CRUD并不复杂,因此不需要DDD.
你描述的是代码气味.但我不认为这是DDD的气味.您只是看到了一个过度设计的代码片段.
我注意到,我们最终遇到了服务层和感觉像代码味道的存储库之间存在重复的情况.
它不是代码味道,因为它们做不同的事情.
您应该记住,域或应用程序服务驻留在与存储库实现不同的层中.层是有原因的 - 不同层中的对象不具有相同的职责,也不与相同的邻居交谈.存储库实现与对象持久性的方式紧密耦合.他们可能会生成SQL语句并与关系数据库交谈,他们可能会与您的ORM交谈......重要的是他们知道对象的持久化方式,而Application Services则不然.
如果您的服务层要直接调用ORM,它实际上会做两件大事,违反单一责任原则.将ORM更改为另一个ORM或使用不同的持久性方法也会更加困难.
因此,例如GetAll将存在于SL和Repository中.现在,如果我们有一个变更/业务要求,GetAll应该忽略某些项目,我应该怎么做,我应该忽略存储库中的这些,还是应该进入服务层的业务逻辑?
如果GetAll()忽略某些项目,我强烈建议在服务和存储库中重命名它以反映它,例如:GetAllAllowedToUser(),GetAllBut...().因此,方法的合同将是明确的,你将避免误解它应该返回什么.另外,您将能够保留原始的正版GetAll()方法,这种方法仍然有用.