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并非银弹
- 概念多,学习成本高,难上手,新手往往不知所措。如果不熟悉DDD的思想,生硬地照搬ddd的规范,写出来的代码可能比传统的三层架构还糟糕,得不偿失。
- 实现一个功能写的代码量比传统的三层架构多
- 模型之间转换操作比较多,编码繁琐
概念
- *领域:某一类业务相关知识的集合,在一个领域下应使用统一语言对概念描述
- *统一语言(UL):从业务中提炼出来的概念术语,领域专家、产品、开发可以互相理解的沟通语言
- *子域:一个子域是领域的一部分
- *实体(Entity):具有唯一标识,有状态(程序需要追踪其状态的变化),具有生命周期、mutable的领域对象
- *值对象(valueObject):没有唯一标识、无状态、无生命周期、可复用、immutable的领域对象,类似基本类型int、long、String
- *聚合:一组具有关联关系领域对象,可包含实体和值对象
- *聚合根:聚合的根,可以理解为可以代表整体概念的实体,操作子实体和值对象需要通过聚合根遍历,类似树形数据结构的根节点,这样可以保证数据的完整性
- *领域事件:某个操作触发的事件,领域事件可以跟踪领域对象生命周期的状态变化过程。例如一个实体经过多次修改,每次产生一个实体修改事件,把所有实体修改事件按发生的顺序可以重建某个时间点的快照对象。领域事件也是同一个用例操作多个聚合的实现方式
- *领域服务:同一个操作中需要操作到多个聚合根对象的逻辑需要抽到领域服务,或者同一个聚合中可以被多个用例复用的公共逻辑
实体和值对象如何区别: 主要是通过有没有唯一标识确定,相同的对象在不同场景可能表现不同,比如用户的收货地址和订单的收货地址,用户的收货地址是实体,而订单的收货地址可能就是值对象,如果用户的收货地址改变,订单的收货地址是不会变的。
开发流程:
- 首先对需要处理的业务问题进行总览。
- 然后领域对象(Entity)进行划分,明确每个领域对象的包含的信息和职责边界。 并进行跨对象,多对象的逻辑组织(Domain Service)
- 接着在上层应用中根据业务描述去编排Entity和Domain Service。
- 最后再做一些下水道工作,去对下层的数据访问,RPC调用去做一些具体实现。
CQRS :
按照领域建模固然很好,但是面对各种各样的查询条件和表单时,仅仅依赖领域对象和聚合来组织代码时,往往会显得很笨拙,但是如果我们放宽对查询的要求,可以在不破坏模型的情况下,尽可能的保证查询的效率和灵活性。这就引出了CQRS
CQRS全称Command Query Responsibility Segregation,即命令查询职责分离,顾名思义,将命令和查询分离。
查询,就是查询数据(CRUD中的R),不会对数据产生变化,因此它是幂等 的,不用担心对系统产生影响,因此也可以针对查询添加缓存操作提升查询性能。
那命令是啥呢?这里命令则是对数据产生变化的操作的总称(CRUD中的CUD)。
大多数软件系统中,查询频率要远大于命令操作,这是将查询与命令分离的根本原因。
通过CQRS模式将读模型和写模型分离,使得我们可以优化读性能和写性能之外,还可以让我们的代码更加清晰简洁,更加体现出领域,更易维护。
一些比较好的例子 CQRS:zhuanlan.zhihu.com/p/505023604
developer.aliyun.com/article/719...
developer.aliyun.com/article/716...
基本概念的解释:blog.csdn.net/g6U8W7p06dC...