5.微服务代码模型

1.微服务代码模型

代码分层

在微服务代码模型里,我们分别定义了用户接口层、并分别为它们建立了interfaces、application、domain和infrastructure四个一级代码目录;

  • interfaces(用户接口层): 它主要存放用户接口层与前端应用交互、数据转换和交互相关的代码;
  • application(应用层): 它主要存放与应用层服务组合和编排相关的代码。应用服务和事件等代码会放在这一层目录里;
  • domain(领域层): 它主要存放与领域层核心业务逻辑相关的代码。聚合内的聚合根以及实体、方法、值对象、领域服务和事件等相关代码会放在这一层目录里;
  • infrastructure(基础层): 它主要存放与基础资源服务相关的代码;

代码目录

  • 用户接口层有assembler、 dto和facade三类;
  • 应用层有event和service。为每个聚合的应用服务设计一个应用服务类;
    对于多表关联的复杂查询,由于这种复杂查询不需要有领域逻辑和业务规则约束,因此不建议将这类复杂查询放在领域层的领域模型中,可以通过应用层的应用服务采用传统多表关联的SQL查询方式;
  • 领域层有entity、event、 repository和service四个子目录;
    domain下的目录结构是由一个或多个独立的聚合目录构成,每一个聚合是一个独立的业务功能单元,多个聚合共同实现领域模型的核心业务逻辑。仓储设计时有—个重要原则: 就是一个聚合只能有一个仓储;
  • 基础层有config和util两个子目录;
    微服务代码目录结构

原则

第一点,聚合之间的代码边界一定要清晰。聚合之间的服务调用和数据关联应该尽可能松耦合和低关联,聚合之间的服务调用应该通过上层的应用层组合实现调用,原则上不允许聚合之间直接调用领域服务。这种松耦合的聚合代码关联,在以后业务发展和需求变更时,可以很方便地实现业务功能和聚合代码的重组,在微服务架构演进中将会起到非常重要的作用;
第二点,一定要有代码分层的概念。写代码时一定要搞清楚代码的职责,将它放在职责对应的代码目录内。应用层代码主要完成服务组合和编排,以及聚合之间的协作,它是很薄的一层,不应该有核心领域逻辑代码。领域层是领域模型的业务的核心,领域模型的核心逻辑代码一定要在领域层实现;

2.设计领域模型

领域层的领域对象

领域模型的聚合内一般会有聚合根、实体、值对象、命令和领域事件等领域对象。完成领域故事分析和微服务设计后,微服务的聚合内一般会有聚合根、实体、值对象、领域事件、领域服务、工厂和仓储、持久化对象等领域对象;

A.设计聚台根

  • 聚合根来源于领域模型,需要找出领域模型内与聚合根关联的所有实体和值对象;
  • 聚合根是一种特殊的实体,需要设计它的属性和方法。同时它也可以管理聚合内实体和值对象等领域对象的生命周期。聚合根可以引用聚合内的所有实体,也可以实现聚合之间的基于聚合根ID的引用;
  • 聚合根类放在领域层聚合的entity目录结构下;

B.设计实体

  • 在DDD分层架构里,实体类采用充血模型,在实体类内实现实体的全部业务逻辑。这些实体有自己的业务属性、方法和业务行为;
  • 大多数情况下,领域模型的实体对象与数据库持久化对象是一一对应的。但领域模型的某些实体在微服务没计时,可能会被设计为一个或多个数据持久化实体,或者实体的某些属性会被设计为值对象;
  • 实体类代码对象放在领域层聚合的entity目录结构下;

C.设计值对象

  • 如果这个领域对象在其他聚合内进行生命周期管理,并且引用它的实体对象只允许对它整体替换,我们就可以将它设计为值对象。如果这个领域对象有多条数据记录且需要基于它进行频繁的查询统计,则建议将它设计为实体;
  • 值对象类放在领域层聚合的entity目录结构下;

D.设计领域事件

  • 如果领域模型中领域事件会触发下一步业务操作,就需要设计领域事件;
  • 领域事件实体类放在领域层聚合的event目录结构下。领域事件的订阅建议放在应用层的event目录结构下。领域事件发布相关代码放在领域层或者应用层都是可以的;

E.设计领域服务

  • 领域服务通过对多个实体和实体方法进行组合和编排,完成多个实体组合的核心业务逻辑。领域服务是位于实体方法之上和应用服务之下的一层业务逻辑;
  • 如果实体方法需要被前端应用调用,需要将它封装成领域服务,然后再封装为应用服务;
  • 一个聚合可以建立一个领域服务类,可以将聚合中所有的领域服务都在这个领域服务类中实现。
  • 领域服务类放在领域层聚合的service目录结构下;

F.设计工厂租仓储

  • 一个聚合只有一个仓储。仓储包括仓储接口和仓储实现,通过依赖倒置原则实现应用业务逻辑与数据库资源逻辑的解耦;
  • 工厂类(factory)放在领域层聚合的service目录结构下。仓储相关代码放在领域层聚合的repository目录结构下;

G.设计持久化对象

  • 持久化对象PO主要完成DO对象的数据库持久化操作, PO一般与数据库表是一对一的关系。为了简化数据库设计,减少数据库表的数量,值对象往往以属性嵌入方式或序列化大对象方式嵌入实体表;
  • 持久化对象PO相关代码放在领域层聚合的repository目录结构下;

应用层的领域对象

应用层主要有应用服务和领域事件的发布和订阅;
在严格分层架构模式下,不允许服务的跨层调用,每个服务只能调用它紧邻的下一层服务。服务从下到上依次为:实体方法、领域服务、应用服务和facade接口;

  • 应用服务会对多个领域服务进行组合和编排,在用户接口层完成服务和数据封装后,就可以发布到API网关,供前端应用调用;
  • 应用服务类放在应用层scrvice目录结构下。领域事件的订阅处理逻辑放在应用层event目录结构下;
  • 服务类的命名参考以下规则: 一般一个聚合只有一个应用服务类,服务前面的名称就可以与聚合名保持一致,然后你可以用*DomainService或*AppService作为后缀,来区分它们是领域服务还是应用服务;

3.微服务调用过程

微服务服务封装

  • 在聚合内采用数据强一致性,在聚合之间采用数据最终一致性。在一次事务中,最多只能修攻一个聚合的数据。如果一次业务交易操作涉及了多个聚合数据的修改,那么应采用领域事件驱动机制。微服务内的领域事件通过事件总线完成聚合之间的异步处理,微服务之间的领域事件通过消息中间件完成。一个聚合对应一个聚合代码目录,聚合之间在代码完全隔离,它们通过应用层的应用服务来协调,完成不同聚合领域服务的组合和编排;
  • 实体采用充血模型,在实体类内部实现实体相关的所有业务逻辑,具体实现形式是实体类中的方法。实体是微服务内的原子业务对象,在设计时我们主要考虑实体自身的属性和业务行为,实现领域模型的核心基础能力。实体方法不会过多考虑外部操作和业务流程,保证领域模型的稳定性。聚合根引用实体和值对象,它可以协调聚合内的多个实体,在聚合根类方法中完成多实体的复杂业务逻辑。但为了职责和边界清晰,建议聚合根自身的业务行为在聚合根类方法中实现,而由多个实体组合实现的业务逻辑由聚合内的领域服务完成;
  • DDD提倡富领域模型,尽量将业务逻辑归属到实体对象上,实在无法归属的部分则设计成领域服务。领域服务会对多个实体或实体方法进行组装和编排,实现跨多个实体的复杂核心业务逻辑。领域服务是介于实体和应用服务之间的薄薄的一层,它的主要职能是实现领域层复杂核心领域逻辑的组合和封装。在领域服务或实体方法中,尽量不要调用其他聚合的领域服务或引用其他聚合的实体或值对象;
  • 应用服务用于组合和编排的服务,主要来源于领域服务,也可以来源于外部微服务的应用服务。除了完成服务的组合和编排外,应用服务内还可以完成安全认证、权限校验、初步的数据校验和分布式事务控制等功能;
    微服务服务封装

微服务数据形态

微服务数据形态

4.微服务解耦策略

微服务之间解耦策略

  • 限界上下文实现了不同业务领域边界的微服务物理边界的解耦;
  • 聚合实现了微服务内不同聚合之间逻辑边界的解耦;
  • 微服务之间通过领域事件和消息中间件,以数据最终—致性的策略,实现了微服务之间的异步调用利服务解耦;
  • 通过适当的数据冗余设计,如值对象的业务快照数据设计,实现了跨微服务不同聚合之间的数据解锅;

微服务内的解耦策略

  • DDD分层架构,通过分层和不同层的职责边界定义,实现了微服务内各层职能和代码的解耦;
  • 用户接口层通过facade接口和数据组装适配,实现了微服务核心业务逻辑与前端应用或用户解耦;
  • 仓储模式通过依赖倒置策略,实现了核心领域逻辑与基础资源处理逻辑的解耦;
  • 微服务代码目录通过聚合目录和分层目录代码边界,实现了不同职能代码边界的解耦,有利于微服务架构演进时代码的组合和拆分;
  • 应用服务通过对不同聚合领域服务的组合和编排,实现了同一个微服务内不同聚合的解耦;
  • 聚合之间通过聚合根ID引用,而不是对象引用方式,完成不同聚合领域对象之间的访问,实现了聚合之间不同领域对象的解耦;
  • 微服务内聚合之间通过事件总线,采用数据最终一致性策略,实现了聚合之间服务同步调用的解耦;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/272747.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一起玩儿物联网人工智能小车(ESP32)——16. 用ESP32的GPIO控制智能小车运动起来(MicroPython)

摘要:本文介绍用MicroPython实现ESP32的GPIO控制智能小车朝各个方向运动 前边的Mixly开发之后,对应生成的代码是C语言的。可能很多人都觉得C语言很难学,现在学Python的人很多,觉得学起来更容易一些。其实,语言本身的难…

探索前端开发趋势:2023年的新兴技术与发展方向

随着科技的不断发展,前端开发领域也在不断演进。本文将详细介绍2023年前端开发的新兴技术和发展趋势,为开发者们指明前端技术的发展方向和面临的挑战。从WebAssembly、PWA到低代码开发,激动人心的全新前景等你探索。 随着科技的快速发展&…

计算机图形图像技术复习资料

一、考试题型 1、简述题(10分4题,共40分) 2、计算题(共10分) 3、编程题(共30分) 4、问答题(共20分) 二、复习提纲 1、简答题 (1)第1章的基本…

平面灯阵中寻找最大正方形边界 - 华为机试真题题解

分值: 300分 题解: Java / Python / C++ 题目描述 现在有一个二维数组来模拟一个平面灯阵,平面灯阵中每个位置灯处于点亮或熄灭,分别对应数组每个元素取值只能为1或0,现在需要找一个正方形边界,其每条边上的灯都是点亮(对应数组中元素的值为1)的,且该正方形面积最大。 …

【hcie-cloud】【12】华为云Stack故障处理【故障处理通用处理原则、常见华为云Stack故障处理(计算域故障场景)】【上】

文章目录 前言故障处理通用处理原则故障处理流程故障信息收集及故障范围、类型识别ManageOne运维面收集告警信息AutoOps工具故障场景信息收集AutoOps工具自动化采集HCS信息 (1)AutoOps工具自动化采集HCS信息 (2)故障初期定位方向故障恢复例行维护讨论: 哪一环比较重要&#xff…

Android studio 花式按键

一、activity_main.xml代码&#xff1a; <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.a…

Xmake v2.8.6 发布,新的打包插件:XPack

Xmake 是一个基于 Lua 的轻量级跨平台构建工具。 它非常的轻量&#xff0c;没有任何依赖&#xff0c;因为它内置了 Lua 运行时。 它使用 xmake.lua 维护项目构建&#xff0c;相比 makefile/CMakeLists.txt&#xff0c;配置语法更加简洁直观&#xff0c;对新手非常友好&#x…

企业级实战项目:基于 pycaret 自动化预测公司是否破产

本文系数据挖掘实战系列文章&#xff0c;我跟大家分享一个数据挖掘实战&#xff0c;与以往的数据实战不同的是&#xff0c;用自动机器学习方法完成模型构建与调优部分工作&#xff0c;深入理解由此带来的便利与效果。 1. Introduction 本文是一篇数据挖掘实战案例&#xff0c;…

深信服技术认证“SCCA-C”划重点:云计算基础

为帮助大家更加系统化地学习云计算知识&#xff0c;高效通过云计算工程师认证&#xff0c;深信服特推出“SCCA-C认证备考秘笈”&#xff0c;共十期内容。“考试重点”内容框架&#xff0c;帮助大家快速get重点知识。 划重点来啦 *点击图片放大展示 深信服云计算认证&#xff08…

华锐视点为广汽集团打造VR汽车在线展厅,打破地域限制,尽享购车乐趣

随着科技的飞速发展&#xff0c;我们正在进入一个全新的时代——元宇宙时代。元宇宙是一个虚拟的世界&#xff0c;它不仅能够模拟现实世界&#xff0c;还能够创造出现实世界无法实现的事物。而汽车行业作为人类生活的重要组成部分&#xff0c;也在积极探索与元宇宙的融合&#…

如何使用ArcGIS Pro将Excel表转换为SHP文件

有的时候我们得到的数据是一张张的Excel表格&#xff0c;如果想要在ArcGIS Pro中进行分析或者制图则需要先转换为SHP格式&#xff0c;这里为大家介绍一下转换方法&#xff0c;希望能对你有所帮助。 数据来源 本教程所使用的数据是从水经微图中下载的POI数据&#xff0c;除了P…

Jenkins 自动设置镜像版本号

使用Jenkins环境变量当作镜像版本号 这样version变量就是版本号,在镜像构建的过程中可以使用 docker build 之后&#xff0c;如果有自己的镜像库&#xff0c;肯定要docker push 一下 至于部署的步骤&#xff0c;一般需要stop并删除原有的容器.我这里用的是docker-compose。同样…

OKCC语音机器人的人机耦合来啦

目前市场上语音机器人的外呼形式基本就分为三种&#xff0c;一种纯AI外呼&#xff0c;第二种也是目前主流的AI外呼转人工。那么第三种也可能是未来的一种趋势&#xff0c;人机耦合&#xff0c;或者也叫人机协同。 那么什么是人机耦合呢&#xff1f; 人机耦合是为真人坐席创造相…

线性代数基础【3】向量

第一节 向量的概念与运算 一、基本概念 ①向量 ②向量的模(长度) ③向量的单位化 ④向量的三则运算 ⑤向量的内积 二、向量运算的性质 (一)向量三则运算的性质 α β β αα (β γ) (α β) γk (α β) kα kβ(k l) α kα lα (二)向量内积运…

什么是GeoTrust?

在当今数字化时代&#xff0c;网络安全是至关重要的。GeoTrust&#xff0c;作为全球领先的SSL证书提供商&#xff0c;致力于为用户提供卓越的数字安全解决方案。 产品与服务&#xff1a; 域名验证证书&#xff1a; 提供快速简便的验证&#xff0c;是保护网站和用户数据的基础。…

华清远见嵌入式学习——ARM——作业4

作业要求&#xff1a; 代码运行效果图&#xff1a; 代码&#xff1a; do_irq.c: #include "key_it.h" extern void printf(const char *fmt, ...); unsigned int i 0;//延时函数 void delay(int ms) {int i,j;for(i0;i<ms;i){for(j0;j<2000;j);} }void do_i…

【linux】Linux重定向

在Linux操作系统中&#xff0c;命令行界面是一个强大的工具&#xff0c;它允许用户与系统进行高效的交互。重定向是命令行中一个非常重要的概念&#xff0c;它可以改变命令输入和输出的默认路径。通过重定向&#xff0c;用户可以将数据从一个程序传递到另一个程序&#xff0c;或…

LENOVO联想笔记本小新Pro 14 IRH8 2023款(83AL)电脑原装出厂Win11系统恢复预装OEM系统

链接&#xff1a;https://pan.baidu.com/s/1M1iSFahokiIHF3CppNpL4w?pwdzr8y 提取码&#xff1a;zr8y 联想原厂系统自带所有驱动、出厂主题壁纸、Office办公软件、联想电脑管家等自带的预装软件程序 所需要工具&#xff1a;16G或以上的U盘 文件格式&#xff1a;ISO 文件…

SpringBoot3 整合Kafka

官网&#xff1a;https://kafka.apache.org/documentation/ 消息队列-场景 1. 异步 2. 解耦 3. 削峰 4. 缓冲 消息队列-Kafka 1. 消息模式 消息发布订阅模式&#xff0c;MessageQueue中的消息不删除&#xff0c;会记录消费者的偏移量 2. Kafka工作原理 同一个消费者组里的消…

开发辅助一(网关gateway+ThreadLocal封装用户信息+远程调用+读取配置文件+统一异常处理)

网关gateway模块 ①、配置文件&#xff0c;添加各个服务模块的路由路径 gateway:routes:-id: server-cart #微服务名称uri: lb://service-cart #负责均衡predicates:- Path/api/order/cart/**ThreadLocal ①、定义一个工具类 public class AuthContextUtil{private static…
最新文章