领域驱动设计-简介 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...

相关推荐
David爱编程30 分钟前
Java 守护线程 vs 用户线程:一文彻底讲透区别与应用
java·后端
小奏技术1 小时前
国内APP的隐私进步,从一个“营销授权”弹窗说起
后端·产品
小研说技术1 小时前
Spring AI存储向量数据
后端
苏三的开发日记1 小时前
jenkins部署ruoyi后台记录(jenkins与ruoyi后台处于同一台服务器)
后端
苏三的开发日记1 小时前
jenkins部署ruoyi后台记录(jenkins与ruoyi后台不在同一服务器)
后端
陈三一1 小时前
MyBatis OGNL 表达式避坑指南
后端·mybatis
whitepure1 小时前
万字详解JVM
java·jvm·后端
我崽不熬夜1 小时前
Java的条件语句与循环语句:如何高效编写你的程序逻辑?
java·后端·java ee
我崽不熬夜2 小时前
Java中的String、StringBuilder、StringBuffer:究竟该选哪个?
java·后端·java ee
我崽不熬夜3 小时前
Java中的基本数据类型和包装类:你了解它们的区别吗?
java·后端·java ee