大纲

  1. 软件设计发展史
  2. 什么是领域驱动设计
  3. 领域驱动设计解决什么问题
  4. 领域驱动设计包含哪些要素
  5. 领域驱动设计的架构
  6. 样例分析

 

软件设计发展史

 

单体->前后端->微服务->服务网格

SSH->ssm->spring boot-> SideCar/ Istio

单体

早期功能侧重功能实现

 

ESB

基于服务总线设计,提供统一的服务管理

https://i-blog.csdnimg.cn/blog_migrate/39cb9cc2a07455ff2775c9cf6c1e6061.jpeg

 

前后端分离

强调重后端,轻前端

 

微服务

各个领域模块服务互不干扰

https://pic1.zhimg.com/80/v2-0882bc64f3f20939876d3433e51fad72_720w.jpg?source=1940ef5chttps://pic1.zhimg.com/80/v2-90388920d31fe35b791c6a92f758db18_720w.jpg?source=1940ef5c

服务网格

将业务功能和治理功能拆分

https://pic2.zhimg.com/80/v2-567a3bd63e4894d1358c6141fca7ba72_720w.jpg?source=1940ef5chttps://pic1.zhimg.com/80/v2-c79af0ff0b1b11ed4586701a3a2e314c_720w.jpg?source=1940ef5c

 

什么是领域驱动设计?

2004年著名建模专家Eric Evans发表了他最具影响力的书籍:《Domain-Driven Design –Tackling Complexity in the Heart of Software》(中文译名:领域驱动设计—软件核心复杂性应对之道),书中提出了“领域驱动设计(简称 DDD)”的概念。设计模式

领域驱动设计事实上是针对OOAD的一个扩展和延伸,DDD基于面向对象分析与设计技术,对技术架构进行了分层规划,同时对每一个类进行了策略和类型的划分。

注:

OOAD(Object Oriented Analysis Design 面向对象分析与设计)

OOP(Object-Orientation Programmin 面向对象编程)

领域驱动设计解决什么问题?

领域驱动设计是一套方法论,指导我们将复杂问题进行拆分、拆分出各个子系统间的关联以及是如何运转的,帮助我们解决大型的复杂系统在落地中遇到的问题。主要体现在以下几点:

  1. 复杂软件系统的设计
  2. 统一认识系统边界
  3. 统一开发知识
  4. 指导开发方式

领域驱动设计包含哪些要素?

领域驱动设计分为战略设计和战术设计。在战略设计层面提出了域、子域、限界上下文等重要概念;在战术设计层面提出了实体、值对象、领域服务、领域事件、聚合、工厂、资源库等重要概念。战略设计部分指导我们如何拆分一个复杂的系统,战术部分指导我们对于拆分出来的单个子系统如何进行落地,在落地过程中应该遵循哪些原则。如下图所示:

 

概念介绍

用户界面层((User)Interface)

负责向用户展现信息以及解释用户命令。更细的方面来讲就是:

 

请求应用层以获取用户所需要展现的数据;

发送命令给应用层要求其执行某个用户命令;

应用层(Application)

很薄的一层,定义软件要完成的所有任务。对外为展现层提供各种应用功能(包括查询或命令),对内调用领域层(领域对象或领域服务)完成各种业务逻辑,应用层不包含业务逻辑。

 

领域层(Domain)

负责表达业务概念,业务状态信息以及业务规则,领域模型处于这一层,是业务软件的核心。

 

基础设施层(Infrastructure)

本层为其他层提供通用的技术能力;提供了层间的通信;为领域层实现持久化机制;总之,基础设施层可以通过架构和框架来支持其他层的技术需求;

子域(Sub Domain)

子域是领域更细粒度的划分,根据重要性与功能将领域分为大致三类的多个子域,分别是核心子域、支撑子域和通用子域。核心域是业务成功的主要促成因素,主要竞争力,支撑子域是支撑核心域的,而通用子域是业务系统的公用部分。支撑子域在领域中是可以有多个的,核心域应该是只有一个为好,当然,除了核心域外,其他子域也可以没有。

核心域是最重要的,开发核心域的解决方案是一种关键性的业务的投入,应该给予核心域的开发最高的优先级和最优秀的开发团队。如果核心域中的一些功能可以从核心域中分离出来,那我们可以用模块的形式从核心域分离出来,这里说的模块其实就是java中说的包,也可以理解为命名空间,文件夹。

限界上下文(Bounded Context)

限界上下文是最难理解的,主要是从一般表述方面来讲,是对于业务流程的一种限制访问约定,一个领域可能会使用多个限界上下文,而限界上下文则有多个不同的服务组成,每个服务可能有多个实体或者之对象及其服务,一般的 java中的package可以看做一个BC。

防腐层(Anticorruption Layer)

对于不同限界上下文的互相访问,采用此类方式完成服务功能,一般的采用Facade模式或Adapter模式开发。

实体(Entity)

实体就是领域中需要唯一标识的领域概念。实体有生命周期,因为我们有时需要区分是哪个实体。有两个实体,如果唯一标识不一样,那么即便实体的其他所有属性都一样,我们也认为他们两个不同的实体.

值对象(Value Object)

在领域中,并不是没一个事物都必须有一个唯一标识,也就是说我们不关心对象是哪个,而只关心对象是什么。就以上面的地址对象Address为例,如果有两个Customer的地址信息是一样的,我们就会认为这两个Customer的地址是同一个。也就是说只要地址信息一样,我们就认为是同一个地址。用程序的方式来表达就是,如果两个对象的所有的属性的值都相同我们会认为它们是同一个对象的话,那么我们就可以把这种对象设计为值对象。因此,值对象没有唯一标识,这是它和实体的最大不同。

领域服务(Domain Service)

领域服务是以动词开头来命名的,协调领域对象共同完成操作或动作。可以细化为三种服务:应用层服务、领域服务、基础服务。

聚合及聚合根(Aggregate,Aggregate Root)

聚合,它通过定义对象之间清晰的所属关系和边界来实现领域模型的内聚,并避免了错综复杂的难以维护的对象关系网的形成。聚合定义了一组具有内聚关系的相关对象的集合,我们把聚合看作是一个修改数据的单元。

可以唯一标识某种场景下的实体可以称为聚合根。

比如 调仓中的indexid和rebalancedate所在的rebalanceConfig对象 可以认为是一个聚合根,而调仓中包含rebalanceConfig对象、elementList对象等对象的root对象rebalanceInfo,称为一个聚合。

工厂(Factory)

一般用于构建聚合对象,保证模型创建时的完整性,比如对象工厂,builder模式。

 

资源库/仓库(Repository)

持久化的封装和实现,或是用于查询服务, 一般是dao层

领域事件(Domain Event)

通过领域事件的方式达到各个组件之间的数据一致性。领域事件是最终一致性而不是事务一致性。

领域驱动设计的架构

三层架构

Conctoller-service-repostory

 

四层架构

Tools-controller-service-domain

https://pic001.cnblogs.com/images/2012/24634/2012102217435351.gif  https://pic2.zhimg.com/80/v2-cdd42c61b143019dbd1881b4614a11a5_720w.jpg

整洁架构(洋葱)

这个架构起作用的最主要原则是依赖原则。这个原则要求源码依赖只能指向内部。内部的圆不能知道外圆的任何事情。一般来说,外圆的声明(包括方法、类、变量或任何软件实体)不能被内圆引用。

 

六边形架构

六边形架构的核心理念是:应用通过"端口"跟外部进行交互的。

首先,通过"内外"的不对称性以及端口的特点,摆脱单维度多层次架构的束缚。可以定义不同数量的端口,2个,3个或者4个,这里说的六边形不限于只有六个边, 可以根据需要加入更多的端口和适配器,"六边形架构"只是视觉上的一种叫法。

 

其次,关注整体架构的结果导向,一个端口对应一个或一组有目的交互行为。但一个端口一般会有多个适配器,可以是无人应答机,语音留言机,按键电话,用户图形界面,测试套件,批处理驱动器,HTTP接口,程序之间的接口,mock的数据库,或者真实的数据库。

 

微服务领域架构

 

CQRS架构

CQRS本身只是一个读写分离的思想,全称是:Command Query Responsibility Segregation,即命令查询职责分离。一个命令表示一种意图,表示命令系统做什么修改,命令的执行结果通常不需要返回;一个查询表示向系统查询数据并返回。另外一个重要的概念就是事件,事件表示领域中的聚合根的状态发生变化后产生的事件,基本对应DDD中的领域事件;

 

CQRS架构的核心出发点是将整个系统的架构分割为读和写两部分,从而方便我们对读写两端进行优化。

https://i-blog.csdnimg.cn/blog_migrate/315471cfdab42667f38c9b9ed4cbd08b.png

事件驱动架构

是一种用于处理事件的生成、发现和处理等任务的软件架构。下图用户阐述如何将事件驱动架构用于多个六边形架构系统。(当然完全可以把六边形架构替换为分层架构或者其他架构)

 

 

样例分析

略。。。

 

延伸阅读

实体对象模型-贫血模型

实体对象模型-充血模型

实体对象模型-胀血模型

设计模式原则-依赖倒置

设计模式原则-接口隔离

设计模式原则-迪米特

设计模式-工厂模式

设计模式-策略模式

设计模式-模板方法

 

 

 

参考资料

单体应用

https://blog.csdn.net/qinaye/article/details/82840625

前后端分离

https://blog.csdn.net/fuzhongmin05/article/details/81591072

https://zhuanlan.zhihu.com/p/29996622

微服务

https://www.zhihu.com/question/65502802

serviceMesh

https://zhuanlan.zhihu.com/p/61901608

https://www.jianshu.com/p/27a742e349f7

领域驱动设计

http://www.javashuo.com/article/p-amaefnfq-bg.html

https://kb.cnblogs.com/page/161050/

https://mp.weixin.qq.com/s/UOr0zRCxy1j__-uaEBt4fA

DDD架构

https://www.bilibili.com/read/cv4633492/

https://zhuanlan.zhihu.com/p/162717871

https://blog.csdn.net/liu_dudu/article/details/113666982

https://www.cnblogs.com/xishuai/p/iddd-soa-rest-and-hexagonal-architecture.html

https://www.deathearth.com/1246.html

领域事件

https://www.deathearth.com/1253.html

https://blog.csdn.net/valada/article/details/100110573

https://www.cnblogs.com/rsapaper/p/8082382.html

六边形架构

https://blog.csdn.net/weixin_36375017/article/details/106347988

https://cloud.tencent.com/developer/article/1560061

 

样例

https://www.jianshu.com/p/Tozpp3

 

 

 

 

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐