领域驱动设计DDD的一点理解 电脑版发表于:2020/10/11 17:00 有人误认为项目架构中加入xxRepository,xxDomain,xxValueObject就变成了DDD架构。如果没有悟出其精髓就在项目中加入这些概念,那充其量也不过是个三层架构;反之对于一个面向对象分析的高手而言,不使用这些概念也可以实现领域驱动设计。 ![](https://img.tnblog.net/arcimg/aojiancc2/3831bfc4877f410b910aa2810b3be42c.png) 一个IUserRepository是一个Repository,方法List<Rule> GetRules(int id)将此Repository打回了原形,这不再是一个Repository,这是一个DAL。 领域驱动,以领域为中心设计,而不是数据为中心。 所以很多人以为用了Repository,Domain这些就是领域驱动,其实不是的,db first的方式还是以数据为中心。先设计领域,先想逻辑,不要管数据库,可以先写领域代码在抽象数据库。 学生在学校的时候从刚开始写代码就开始学习各种设计模式各种数据结构,但是很少有机会用过?因为你所写的代码无时无刻不耦合着数据库。数据库操作作为一种实现细节掺杂在你的代码中,所以领域驱动设计就是为了讲解这种问题的 #### DDD中的Repository模式 Repository模式也称存储库模式或仓储模式,根据Eric Evans的《领域驱动设计》一书,“存储库是一种封装存储,检索和搜索行为的机制,它模仿对象的集合。” 同样,根据企业应用程序体系结构的模式,它“使用类似集合的接口访问域对象,在域和数据映射层之间进行中介”。 换句话说,存储库还处理数据并隐藏类似于DAO的查询。但是,它处于更高的层次,更接近应用程序的业务逻辑。 Repository模式又称为仓储模式或存储库模式,替代以前的DAO模式,存储库模式限制我们在应用程序直接使用数据库的数据。 ##### Repository设计原则 - 出参入参不应该使用底层数据格式: 需要记得的是 Repository 操作的是 Entity 对象(实际上应该是Aggregate Root),而不应该直接操作底层的 DO 。更近一步,Repository 接口实际上应该存在于Domain层,根本看不到 DO 的实现。这个也是为了避免底层实现逻辑渗透到业务代码中的强保障。 - 不要在仓储内控制事务: 你的仓储用于管理的是单个聚合,事务的控制应该取决于业务逻辑的完成情况,而不是数据存储与更新情况。 ####数据驱动的方式开始很简单,随着业务越来越复杂 ![](https://img.tnblog.net/arcimg/aojiancc2/716ff19e41d443aa9344831b58a4e5ba.jpg) 领域驱动最开始做的事情就比较多,设计模式面试对象分析,领域驱动会麻烦一些,这些确定好了在提取数据库 编码的过程中,一些业务与流程完全是与数据无关的,数据库仅仅起到了持久化的任务,数据从业务逻辑中抽离。 ####建议的n层架构高层次图 ![](https://img.tnblog.net/arcimg/aojiancc2/bfcfd90064db45a1ac5a9d3f67124e58.png) 最上层是提供接口了,最下面是基础设置层,基础设施层每一层都可以直接访问它,都能有箭头直接指下来。 ![](https://img.tnblog.net/arcimg/aojiancc2/9cd2b36712c94441b4ba55bd9d25cef3.png) DDD落地实现离不开Clean架构、六边形架构、 CQRS、Event Source几大大相关领域。下图是传统以数据库为中心的架构与使用DDD实现以领域为中心架构的区别。 ![](https://img.tnblog.net/arcimg/aojiancc2/ae35813ebcb44662ab7008be12071da5.png) DDD专门为解决复杂性而诞生,因此解决思路完全不同于传统的CRUD,但是DDD本身掌握起来并不会感觉复杂,从程序员角度看,DDD其实是研究将包含业务逻辑的ifelse语句放在哪里的学问。 ![](https://img.tnblog.net/arcimg/aojiancc2/462ce5db9e1d4021acc345d318967a7b.png)