大家好,我是Louis,在DDD领域有8年的实战经验,曾指导多个团队落地DDD项目。
今天我要用一张图讲清楚DDD+CQRS架构,看懂这张图,DDD就学会了。 不废话,直接上图:
DDD+CQRS架构
DDD的全称是领域驱动设计 Domain Driven Design,是广泛应用于系统架构设计的一种方法论。
目前业界对DDD的态度实际上褒贬不一,有些人觉得很牛,有些人觉得一文不值。但据我观察,持否定态度的人多数是半懂不懂,只是听别人说“很复杂”,自己往往说不出个所以然来。当然也确实有一些大牛分析到,DDD应用在中小型项目中会显得有些臃肿,这我是认可的,但遗憾的是我也并未看到有人提供了更优解。
我本人并不是DDD的狂热拥趸,只是它确实给了我一种解决问题的思路,并且我认为行之有效。但若你有更好的解决方案,我也十分愿意请教。
如果你对DDD一知半解,我另外有一篇文章《三句话说清DDD的思想内核》,希望能带你入门
这张图我是反反复复推敲了好几年,也参考了许多业界大佬的思路,最终形成此图。
接下来我们沿着这张图,来聊一聊DDD的分层架构,你会看到这其中的设计十分巧妙。
基础设施层 infrastructure 处在架构的最外围,这一层与业务规则完全无关。
基础设施层就像是城堡的城墙,把城堡围与外部隔开,入口网关、出口网关就是城堡的大门
接口定义层 interface layer只定义接口不实现,这里用到的是facade模式,统一把系统对外的服务包装成接口
我这里借鉴了CQRS架构模式(Command Query Responsibility Segregation),把facade api
和query api
分开,除了可以做读写分离以外,更重要的原因是有些业务的查询特别复杂,例如电商业务,用户打开一个页面除了要查询商品,还要查优惠券、推荐、关系链等,这时候把Command和Query分开是很好的选择。
Query请求是不需要经过应用服务层的,可以直接查询数据库、缓存等。
也叫应用服务层 Application Service
facade api
,这样系统才能提供完整服务。facade接口定义是与用例分析密切相关的,可以参考《为什么说用例设计在软件开发中很重要》
不写业务逻辑的意思是:不做逻辑判断、不做数值计算、没有业务规则
领域层Domain Layer包含了核心的业务规则,大致上又能分为这几个部分
领域服务对应的是《为什么说用例设计在软件开发中很重要》这篇文章中的二级、三级用例。 另外很多人反感Java代码每一层都要定义接口和实现,即便实现类永远只有一个。我同样也反感。所以人是要变通的,interface层的接口是为了做内外隔离,是必须的,而Domain Service定义接口则完全没必要
还有一个相对特殊的是types,由于值对象是定义在领域层,按照规范,facade api
是不能直接依赖领域层的,但又有部分值对象或枚举值很通用,为了简化代码,可以把这些相对通用的类型放在types里面。
这篇文章先简要概括了DDD的分层架构,以及每一层的职责。篇幅原因没有讲每一层的设计原则和设计范式,后续还会再详细说明。
我知道大家很关心是否有demo代码可以参考。有!不仅有示例代码,还有配套的框架和工具! 只是这部分工作量稍微有点大,还需要一段时间。后续也会拿示例代码进行直播讲解,尽请关注。