前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >DDD是如何解决复杂业务扩展问题?

DDD是如何解决复杂业务扩展问题?

作者头像
微观技术
发布2020-08-20 15:25:32
1.8K0
发布2020-08-20 15:25:32
举报
文章被收录于专栏:微观技术

业务初期,功能比较简单,CRUD基本可以满足。但随着系统的不断演化,业务系统越来越复杂,各模块间有着千丝万缕的关系,如何提升其扩展性,避免牵一发而动全身,是我们非常关心的。

我们会想到重构,重构伴随在业务迭代的整个生命周期里。保持行为不变的代码改善清除了不协调的局部设计。克服演进式设计中大杂烩问题的主力,通过在单独的类及方法级别上做一系列小步重构来完成。

早年的J2EE开发模式,讲究 Web/Service/Dao 三层结构。面向过程编程,对象只是数据的载体,没有行为。以数据为中心,以数据库ER设计作驱动。分层架构在这种开发模式下,可以理解为是对数据移动、处理和实现的过程。该对象我们称之为贫血领域对象。

贫血领域对象(Anemic Domain Object):是指仅用作数据载体,而没有行为和动作的领域对象。大量的业务逻辑写在了Service层中,随着业务逻辑复杂,业务逻辑、状态会散落在Service层中的很多处理类或方法中。将数据和行为割裂,原来的代码意图会越来越模糊,代码的理解和维护成本会越来越高。

如何设计复杂的业务系统

概要来讲分为三块:拆分、抽象、DDD

1、拆分。分为业务维度、技术维度。

业务维度把大的问题域拆分成若干小的业务子域。这样容易实现人员、资源的聚焦。但要考虑如何拆分的合理性,注重高内聚低耦合。

技术维度主要是软件分层,如MVC,讲究的模块化、组件化,预留接口,支持扩展。

2、抽象。物质决定意识,万事万物都有原型。根据达尔文的进化论,万物都有自己的特征,相似的物种可以归类到一个属、科等。软件也是一样的道理,将相似的业务聚拢,底层模型统一化设计,并要支持好扩展性。

3、DDD。至少30年以前,一些软件设计人员就已经意识到领域建模和设计的重要性,并形成一种思潮,Eric Evans将其定义为领域驱动设计(Domain-Driven Design,简称DDD),将数据和行为封装在一起,并与现实世界中的业务对象相映射。各类具备明确的职责划分,将领域逻辑分散到领域对象中。

DDD核心组成

1、实体

当一个对象由其标识(而不是属性)区分时,这种对象称为实体(Entity)。

例:最简单的,公安系统的身份信息录入,对于人的模拟,即认为是实体,因为每个人是独一无二的,且其具有唯一标识(如公安系统分发的身份证号码)

2、值对象

当一个对象用于对事物进行描述而没有唯一标识时,它被称作值对象(Value Object)。

例:比如颜色信息,我们只需要知道{“name”:“黑色”,”css”:“#000000”}这样的值信息就能够满足要求了,这避免了我们对标识追踪带来的系统复杂性。

3、聚合根

Aggregate(聚合)是一组相关对象的集合,作为一个整体被外界访问,聚合根(Aggregate Root)是这个聚合的根节点。

聚合由根实体,值对象和实体组成。如:一个电脑包含硬盘、CPU、内存条等,这一个组合就是一个聚合,而电脑就是这个组合的聚合根。在聚合中,根是唯一允许外部对象保持对它的引用的元素,而边界内部的对象之间则可以互相引用。

4、领域服务

当我们在分析某一领域时,一直在尝试如何将信息转化为领域模型,但并非所有的点我们都能用Model来涵盖。对象应当有属性,状态和行为,但有时领域中有一些行为是无法映射到具体的对象中的,我们也不能强行将其放入在某一个模型对象中,而将其单独作为一个方法又没有地方,此时就需要服务。

服务是无状态的,对象是有状态的。所谓状态,就是对象的基本属性:高矮胖瘦。服务本身也是对象,但它却没有属性(只有行为),因此说是无状态的。

5、领域事件

领域事件是对领域内发生的活动进行的建模。

6、限界上下文

一个由显示边界限定的特定职责。领域模型便存在于这个边界之内。在边界内,每一个模型概念,包括它的属性和操作,都具有特殊的含义。

一个给定的业务领域会包含多个限界上下文,想与一个限界上下文沟通,则需要通过显示边界进行通信。系统通过确定的限界上下文来进行解耦,而每一个上下文内部紧密组织,职责明确,具有较高的内聚性。

一个很形象的隐喻:细胞质所以能够存在,是因为细胞膜限定了什么在细胞内,什么在细胞外,并且确定了什么物质可以通过细胞膜。

如何划分限界上下文?

我们的实践是,考虑产品所讲的通用语言,从中提取一些术语称之为概念对象,寻找对象之间的联系;或者从需求里提取一些动词,观察动词和对象之间的关系;我们将紧耦合的各自圈在一起,观察他们内在的联系,从而形成对应的界限上下文。形成之后,我们可以尝试用语言来描述下界限上下文的职责,看它是否清晰、准确、简洁和完整。简言之,限界上下文应该从需求出发,按领域划分。

7、资源库(Repositories)

资源库的是封装所有获取对象引用所需的逻辑。领域对象不需处理基础设施,以得到领域中对其他对象的所需的引用。只需从资源库中获取它们,于是模型重获它应有的清晰和焦点。

资源库会保存对某些对象的引用。当一个对象被创建出来时,它可以被保存到资源库中,然后以后使用时可从资源库中检索到。如果客户程序从资源库中请求一个对象,而资源库中并没有它,就会从存储介质中获取它。换种说法是,资源库作为一个全局的可访问对象的存储点而存在。

Repository的接口应当采用领域通用语言。作为客户端,不应当知道数据库实现的细节。

Repository和DAO的作用类似,二者的主要区别:

DAO是比Repository更低的一层,包含了如何从数据库中提取数据的代码。

Repository以“领域”为中心,所描述的是“领域语言”。Repository把ORM框架与领域模型隔离,对外隐藏封装了数据访问机制。

DDD四层架构

1、User Interface 接口层,主要用于处理用户发送的Restful请求、解析用户输入信息、校验等,并将信息传递给Application层的接口。

2、Application为应用层,定义软件要完成的任务,并且指挥表达领域概念的对象来解决问题。这一层所负责的工作对业务来说意义重大,也是与其它系统的应用层进行交互的必要渠道。应用层要尽量简单,不包含业务规则或者知识,而只为下一层中的领域对象协调任务,分配工作,使它们互相协作。它没有反映业务情况的状态,但是却可以具有另外一种状态,为用户或程序显示某个任务的进度。

3、Domain为领域层(或模型层),负责表达业务概念,业务状态信息以及业务规则。尽管保存业务状态的技术细节是由基础设施层实现的,但是反映业务情况的状态是由本层控制并且使用的。领域层是业务软件的核心,领域模型位于这一层。

4、Infrastructure为基础设施层,为其他层提供通用的技术能力:业务平台,编程框架,持久化机制,消息机制,第三方库的封装,通用算法,等等

DDD六边形架构

DDD分层架构中的低层组件应该依赖于高层组件提供的接口,即无论高层还是低层都依赖于抽象,整个分层架构好像被推平了。如果我们把分层架构推平,再向其中加入一些对称性,就会出现一种具有对称性特征的架构风格,即六边形架构。六边形架构是Alistair Cockburn在2005年提出的,在这种架构中,不同的客户通过“平等”的方式与系统交互。需要新的客户吗?不是问题。只需要添加一个新的适配器将客户输入转化成能被系统API所理解的参数就行。同时,对于每种特定的输出,都有一个新建的适配器负责完成相应的转换功能。

DDD和微服务什么关系

随着微服务架构的不断流行,很多企业开始在自己的业务中推行微服务。但在实际落地过程中,总是遇到各种边界问题。DDD中的限界上下文则完美匹配微服务要求,可以将该限界上下文理解为一个微服务进程。DDD在面向高度复杂的软件系统,如何去建模,它的核心点是根据系统的复杂度建立合适的模型。

DDD 的一个生命周期是这样的:在设计和实现一个系统的时候,业务领域专家和开发人员以一套统一语言进行协作,共同完成领域模型的构建,在这个过程中,业务架构和系统架构等问题都得到了解决,之后将领域模型中关于系统架构的主体映射为实现代码,完成系统的实现落地。

DDD的本质是一种软件设计方法,而微服务是具体的落地实现。

在微服务架构实践中,人们大量地使用了DDD中的概念和技术,注意事项

1、微服务中应该首先建立UL(Ubiquitous Language,通用语言),然后再讨论领域模型。

2、一个微服务最大不要超过一个BC(Bounded Context,限界上下文),否则微服务内会存在有歧义的领域概念。

3、一个微服务最小不要小于一个聚合,否则会引入分布式事务的复杂度。

4、微服务的划分过程类似于BC的划分过程,每个微服务都有一个领域模型。

5、微服务间的集成可以通过Context Map来完成,比如ACL(Anticorruption Layer,防腐层)。

6、微服务间最好采用Domain Event(领域事件)来进行交互,使得微服务可以保持松耦合。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微观技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档