领域驱动设计-简介 DDD(Domain-Driven Design)

Domain-driven design (DDD ) is a major software design approach, focusing on modelling software to match a domain according to input from that domain's experts. ---wikipedia

领域驱动是一种软件设计方式,聚焦于软件模型和领域专家(十分了解具体业务的人)的输出相匹配。

解决软件开发存在的问题

软件总是从简单发展到复杂,老化的原因主要是,真实世界和软件世界存在差异,并随着需求变更逐渐拉大。

传统数据驱动设计存在的问题

传统MVC架构倾向于从数据库ER图开始进行设计。随着业务越来越多,变化越来越,事务脚本会越来越复杂,可能一个类里面有大量的逻辑。这时候系统将逐渐老化。

从数据驱动到领域驱动

Data Driven Design --> Domain Driven Design

领域驱动设计是一种面向变化的一种设计,设计的核心模型从数据驱动的数据库表转移到领域模型。领域模型将由开发人员和领域专家共同设计,这样实际的模型将更贴近真实世界。

优点

  • 代码更贴近真实世界,需求调整变更 更容易
  • 逻辑更内聚,代码复用度更高,也更易于测试
  • 业务逻辑不再需要背负技术债,根据业务场景变化开发即可

缺点

DDD并非银弹

  1. 概念多,学习成本高,难上手,新手往往不知所措。如果不熟悉DDD的思想,生硬地照搬ddd的规范,写出来的代码可能比传统的三层架构还糟糕,得不偿失。
  2. 实现一个功能写的代码量比传统的三层架构多
  3. 模型之间转换操作比较多,编码繁琐

概念

  • *领域:某一类业务相关知识的集合,在一个领域下应使用统一语言对概念描述
  • *统一语言(UL):从业务中提炼出来的概念术语,领域专家、产品、开发可以互相理解的沟通语言
  • *子域:一个子域是领域的一部分
  • *实体(Entity):具有唯一标识,有状态(程序需要追踪其状态的变化),具有生命周期、mutable的领域对象
  • *值对象(valueObject):没有唯一标识、无状态、无生命周期、可复用、immutable的领域对象,类似基本类型int、long、String
  • *聚合:一组具有关联关系领域对象,可包含实体和值对象
  • *聚合根:聚合的根,可以理解为可以代表整体概念的实体,操作子实体和值对象需要通过聚合根遍历,类似树形数据结构的根节点,这样可以保证数据的完整性
  • *领域事件:某个操作触发的事件,领域事件可以跟踪领域对象生命周期的状态变化过程。例如一个实体经过多次修改,每次产生一个实体修改事件,把所有实体修改事件按发生的顺序可以重建某个时间点的快照对象。领域事件也是同一个用例操作多个聚合的实现方式
  • *领域服务:同一个操作中需要操作到多个聚合根对象的逻辑需要抽到领域服务,或者同一个聚合中可以被多个用例复用的公共逻辑

实体和值对象如何区别: 主要是通过有没有唯一标识确定,相同的对象在不同场景可能表现不同,比如用户的收货地址和订单的收货地址,用户的收货地址是实体,而订单的收货地址可能就是值对象,如果用户的收货地址改变,订单的收货地址是不会变的。

开发流程:

  1. 首先对需要处理的业务问题进行总览。
  2. 然后领域对象(Entity)进行划分,明确每个领域对象的包含的信息和职责边界。 并进行跨对象,多对象的逻辑组织(Domain Service)
  3. 接着在上层应用中根据业务描述去编排Entity和Domain Service。
  4. 最后再做一些下水道工作,去对下层的数据访问,RPC调用去做一些具体实现。

CQRS :

按照领域建模固然很好,但是面对各种各样的查询条件和表单时,仅仅依赖领域对象和聚合来组织代码时,往往会显得很笨拙,但是如果我们放宽对查询的要求,可以在不破坏模型的情况下,尽可能的保证查询的效率和灵活性。这就引出了CQRS

CQRS全称Command Query Responsibility Segregation,即命令查询职责分离,顾名思义,将命令和查询分离。

查询,就是查询数据(CRUD中的R),不会对数据产生变化,因此它是幂等 的,不用担心对系统产生影响,因此也可以针对查询添加缓存操作提升查询性能。

那命令是啥呢?这里命令则是对数据产生变化的操作的总称(CRUD中的CUD)。

大多数软件系统中,查询频率要远大于命令操作,这是将查询与命令分离的根本原因。

通过CQRS模式将读模型和写模型分离,使得我们可以优化读性能和写性能之外,还可以让我们的代码更加清晰简洁,更加体现出领域,更易维护。

一些比较好的例子 CQRS:zhuanlan.zhihu.com/p/505023604

developer.aliyun.com/article/719...

juejin.cn/post/713118...

developer.aliyun.com/article/716...

基本概念的解释:blog.csdn.net/g6U8W7p06dC...

相关推荐
哎呦没20 分钟前
SpringBoot框架下的资产管理自动化
java·spring boot·后端
2401_8576009523 分钟前
SpringBoot框架的企业资产管理自动化
spring boot·后端·自动化
NiNg_1_2344 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
Chrikk6 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*6 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue6 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man6 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang
customer088 小时前
【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源