使用领域模式可以提升系统的内聚性和可重用性,通过不同类之间的协同完成所有功能。另外,多态的模式也让扩展新的策略更加方便,业务语义更加通用、显性化。领域建模过程遵循“SOLID”原则并实现业务域的逻辑解决方案。
说明:SOLID原则
1.Single Responsibility Principle:单一职责原则;
2.Open Closed Principle:开闭原则3.Liskov Substitution Principle:里氏替换原则;
4.Interface Segregation Principle:接口隔离原则;
5.Dependence Inversion Principle:依赖倒置原则;
领域驱动设计核心要素
如下图所示是领域驱动设计的核心要素,包含领域驱动设计中的通用模型术语和重要的战术模式。这些模式不仅可以捕获和传递领域中的概念、关系及逻辑,也能帮助我们管理业务的复杂性并确保领域模型的行为清晰明确。
● 领域:相对于软件系统来说就是系统要解决的现实问题。
● 子域:对于领域进行不同维度切分的相对内聚的子系统单元。
● 分层架构:通过分层架构将业务域和技术逻辑域隔离。
● 服务:服务通常是领域对象的调用方,用来协调领域对象完成指定业务逻辑职责。
● 实体:实体与面向对象中的概念类似,它是领域模型的基本元素,在领域模型中,实体应该具有唯一的标识符。
● 值对象:值对象是没有唯一标识符的实体。值对象在领域模型中是可以被共享的,它们应该是不可变的,当有其他地方需要用到值对象时,可以将它的副本作为参数传递。
● 聚合:聚合使用边界将内部和外部的对象划分开来。每个聚合有
《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》
【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享
一个根,这个根是一个实体作为外部可以访问的唯一对象。
● 资源库:是封装的所有获取对象引用所需的逻辑单元。
● 工厂:工厂用来封装对象创建所必需的信息,当聚合根建立时,所有聚合包含的对象将随之建立。
专注问题域
=====
解决一个业务场景中的复杂问题从理解问题域开始,通过专注于问题域并理解复杂问题背后的实质,你才能设计有效的模型来应对业务的挑战。在项目初期,尽量避免沉溺于技术实现,而要把焦点集中在问题领域,不要忘记技术服务业务的原则。
理解问题域
我们以一个金融场景下的“业务运营监控系统”为例进行分析。
经过与运营管理专家和相关业务方的多轮需求探论,我们初步了解了用户的业务诉求和痛点。需要强调的是对于问题域的充分理解是我们的首要任务。
这里整理了一份需求文档,它详细地记录了问题域的具体范围和详细需求。这份文档不仅是业务与技术团队之间的一份沟通文档,也可以作为软件生命周期在需求分析阶段的一个清晰的、规范化的知识协作产物。
提炼问题域
理解复杂问题并从中识别、提炼出关键的业务模型,即提炼问题域是领域驱动设计的关键环节。团队可以通过头脑风暴的形式罗列出领域中的所有事件,整合之后形成最终的领域事件集合。
你需要在关键事件标记的范围里,参照不同利益干系方的业务诉求,组织领域事件和模型,同时,你需要整理出与项目关联的上下游系统,如下图所示。
通过挖掘隐藏在领域事件中的核心领域模型,我们可以找到从问题空间到方案空间的对应映射关系。针对上述业务监控系统案例,“进件存量”和“进件流量”的概念成为我们发现的重要领域模型。
作为衡量业务系统运转状态的重要指标,业务的“存量”状态可以表示业务的积压情况,而业务的“流量”状态可以表示业务流转的变化情况。
如下图所示是我们总结的监控系统概要视图,其中实线表示的是城市信贷业务工作流中进件在不同系统的流向,而虚线表示的则是业务的存量、流量在业务监控系统的事件记录。
服务的拆分
=====
完成问题域的理解和提炼后,我们需要对整体系统做进一步的服务拆分。下图是我们根据业务领域能力对“业务运营监控系统”进行拆分后的子领域服务及模块划分说明。
● 业务事件收集(如下图和表所示)
● 事件过滤聚合(如下图和表所示)
● 规则配置(如下图和表所示)
● 监控查询展示(如下图和表所示)
为什么要做服务拆分
● 降低系统的整体复杂性:根据业务领域进行合理的服务拆分是一个有效控制系统复杂性的方法。
● 提高效率:服务拆分后,代码模块相互隔离,并发的开发模式可以提升开发人员的效率。
● 团队人员各司其职:拆分的项目可分派给擅长相关方面技术的人员,让团队成员各司其职,降低工作的耦合度。
● 共享和自治:可以通过定义好的服务接口进行服务共享,同时拆分后的服务也更加自治。
● 解决依赖问题:通过服务拆分,可以清晰地了解哪些服务依赖会对业务造成影响,从而准备预案。
服务拆分的依据
高内聚、低耦合是服务拆分的主要依据,下面我们列举一些常用的服务拆分策略,了解如何对单体架构进行拆分。
● 区分服务类型:工具服务区别于业务服务,它的特点是与业务领域无关,根据其用途可以进一步细分,一般包括的形式有公共工具服务、资源工具服务、包装器服务等。
● 根据功能定义划分服务:领域驱动设计通过分析问题空间和业务逻辑,将应用程序定义为域,域由多个子域组成,每个子域对应于业务的不同功能部分。
● 根据技术边界划分服务:对于产品类型的服务使用技术能力划分服务边界,前后端分离架构就是通过技术栈划分服务边界的典型架构模式。
服务拆分范式
通过增加服务实例或者机器来解决服务的容量和可用性问题是常用的可扩展架构解决方案。在《可扩展艺术》一书中提出了系统的可扩展性模型:AKF可扩展立方,可以作为服务拆分的范式。
如下图所示是使用Scale Cube的3D模型实现的一个微服务架构模型,在X轴上通过API网关进行水平扩展,在Y轴上进行单体拆分后的微服务构建,服务之间可以通过REST API进行简单交互,Z轴是数据维度的拆分。
● X轴:服务扩展,通过克隆的方式水平扩展。一般是负载均衡后运行多个应用副本,达到某个服务的高吞吐量和高可用性。
● Y轴:功能拆分,通过拆分不同的事务进行扩展。微服务对应着Y轴,即将单体应用拆分为微服务应用。
● Z轴:数据分区,通过分隔相同的事务进行扩展,例如数据库分库分表。
总之,服务支持水平扩展以提升容量;对功能的拆分体现在对业务模型的切入和深入理解上;应用数据的划分是微服务的重要原则,如果数据的耦合问题无法解决,那么应用服务的划分还会有代码耦合和级联影响。
界限上下文
=====
在找到服务边界并把系统拆分后,我们需要使用“界限上下文”的概念明确服务之间的交互共享模型和行为接口,它不仅可以有效地限定领域的职责边界和特性范围,也可以控制问题域的规模,进而以化整为零的方式控制整个系统的复杂性。
在业务运营监控项目中,存量项模型作为业务过滤聚合服务和存量查询统计服务的共享模型,关系如下图所示。
为了实现捕获和统计监控业务运营过程中的不同阶段存量的业务状态,我们将存量项作为上述两个服务上下文的共享模型,但我们不会暴露“过滤聚合服务”中的存量明细、Flow、Stream等模块的实现细节。
作为两个独立的服务主体,它们应该在边界上有明确的界线划分和通信机制。如果服务边界与领域的界限上下文能够保持一致,那么我们已经为高内聚、低耦合的微服务架构实现了关键的一步。
领域建模
====
领域建模是领域驱动设计的核心,通过领域模型可以封装对业务的抽象,建立业务概念与领域规则的关系。领域模型更关注的是业务语义的显性表达,而不是具体的数据存储及代码逻辑实现细节,它可以有效地降低业务人员和技术人员之间的沟通成本。
案例分析
回到“业务运营监控系统”中,我们把业务监控的核心诉求聚焦在“业务事件”,以及业务的存量和流量领域模型。在整理了领域服务的核心模块后,我们可以把业务方关注的组织信息、业务类型信息、业务阶段信息进行进一步领域模型细化,如下图所示。
● BizEvent:业务事件是业务监控的数据源,使用统一的JSON格式记录消息事件,以日志方式封装当前业务系统发生的事件详情。