软件设计不是CRUD(16):低耦合模块设计理论——行为抽象与设计模式(下)

(接上文《软件设计不是CRUD(15):低耦合模块设计理论——行为抽象与设计模式(中)》)

3.2.4、之前的业务逻辑需要关注后续逻辑的执行成败,并调整自身执行的情况

这个场景在之前场景的基础上增加了新的控制要求,具体来说就是之前已经完成的控制逻辑执行,需要在后续控制逻辑执行出现问题时,获得一种错误补偿的方式。这和我们常说的数据库事务还有所区别(当然数据库事务回滚也是必要的一种错误补偿方式),因为错误补偿不一定是数据库事务回滚。

这实际上也是在之前介绍的单个业务控制点的基础上,对一个业务维度的多个实现进行错误补偿控制方式的一种扩充。只不过这里需要解决的是一个控制逻辑上,多个业务控制点之间如何协进行调错误补偿的问题。这里推荐一种命令模式的设计方式,如下图所示:

在这里插入图片描述
为什么这里需要将具体结算单的策略传入到命令中,这是因为不可能为某一种具体的结算单创建一种对应的命令,例如不可能为SettlementA这种类型的结算单创建专门的一种转换命令,然后再为SettlementB这种类型的结算单创建专门的一种转换命令,否则可能会导致类爆炸(类爆炸的概念在前文中介绍过,这里不再赘述,导致类爆炸的原因主要是因为维度合并,且设计无法控制维度扩展)。

  • 这是命令接口的定义
// 结算单执行命令
public interface SettlementCommand {// 命令执行方法public void doCommand();// 用于在控制逻辑出现错误的情况下// 要求具体命令的业务执行过程进行错误补偿public void redo(Throwable e);
}
  • 对结算单信息进行验证的命令
// 对结算单信息进行验证的命令
public class ValidateSettlementCommand implements SettlementCommand {private SettlementStrategy<Settlement> settlementStrategy;private Settlement settlement;// =======// 这里有一个构造方法,为了节约篇幅省去// =======@Overridepublic void doCommand() {if(this.settlementStrategy.needValidate(settlement)) {this.settlementStrategy.validate(settlement);}}@Overridepublic void redo() {// 该验证命令在整个控制逻辑出现问题时,不用做对应的错误补偿}
}
  • 对结算单信息进行信息转换的命令
// 对结算单信息进行信息转换的命令
public class BalanceSettlementCommand implements SettlementCommand {private SettlementStrategy<Settlement> settlementStrategy;private BalanceStrategy balanceStrategy;private Settlement settlement;// =======// 这里有一个构造方法,为了节约篇幅省去// =======@Overridepublic void doCommand() {this.settlementStrategy.balance(settlement, balanceStrategy);}@Overridepublic void redo() {// 当整个控制逻辑发生错误时,该命令需求重置已设定的结算费用,并清理数据库中的设定信息}
}
  • 发送事件通知的命令
// 发送事件通知的命令
@Slf4j
public class SendEventSettlementCommand implements SettlementCommand {private Settlement settlement;@Autowired(required = false)private List<SettlementEventListener> settlementEventListeners;public SendEventSettlementCommand(Settlement settlement) {this.settlement = settlement;}@Overridepublic void doCommand() {if(CollectionUtils.isEmpty(this.settlementEventListeners)) {return;}// 对上层模块进行事件通知for (SettlementEventListener settlementEventListener : settlementEventListeners) {try {settlementEventListener.onBalanced(settlement);} catch(RuntimeException e) {log.error(e.getMessage() , e);}}}@Overridepublic void redo() {

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

以太网/USB 数据采集卡 24位16通道 labview 256K同步采样

XM7016以太网SUB数据采集卡 XM7016是一款以太网/USB高速数据采集卡&#xff0c;具有16通道真差分输入&#xff0c;24位分辨率&#xff0c;单通道最高采样率256ksps. 16通道同步共计4.096Msps、精密前置增益放大、集成IEPE/ICP硬件支持的特点。本产品采用了多个高精度24位ADC单元…

leetcode-链表算法题

leetcode-链表算法题 237.删除链表中的节点 题目地址 有一个单链表的 head&#xff0c;我们想删除它其中的一个节点 node。 给你一个需要删除的节点 node 。你将 无法访问 第一个节点 head。 链表的所有值都是 唯一的&#xff0c;并且保证给定的节点 node 不是链表中的最后一个…

20240322-2-Catboost面试题

Catboost面试题 1. 简单介绍Catboost&#xff1f; CatBoost是一种以对称决策树 为基学习器的GBDT框架&#xff0c;主要为例合理地处理类别型特征&#xff0c;CatBoost是由Categorical和Boosting组成。CatBoost还解决了梯度偏差以及预测偏移的问题&#xff0c;从而减少过拟合的…

element plus的el-image图片发布到nginx不显示

问题&#xff1a; <el-image alt""src"/img/month-b.png" class"card-icon"style"width: 89px;height: 89px;right: -7px;top: -5px;"/> 部署到nginx二级路由访问地址是&#xff1a; http://192.168.1.207/divided/# 这时候使用…

使用node爬取视频网站里《龙珠》m3u8视频

1. 找到视频播放网站 百度一下 龙珠视频播放 精挑细选一个可以播放的网站。 如&#xff1a;我在网上随便找了一个播放网站&#xff0c;可以直接在线播放 https://www.xxx.com/play/39999-1-7.html 这里不具体写视频地址了&#xff0c;大家可以自行搜索 2.分析网页DOM结…

【面试经典150 | 动态规划】三角形最小路径和

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;动态规划 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容进行…

使用pytorch构建带梯度惩罚的Wasserstein GAN(WGAN-GP)网络模型

本文为此系列的第三篇WGAN-GP&#xff0c;上一篇为DCGAN。文中仍然不会过多详细的讲解之前写过的&#xff0c;只会写WGAN-GP相对于之前版本的改进点&#xff0c;若有不懂的可以重点看第一篇比较详细。 原理 具有梯度惩罚的 Wasserstein GAN (WGAN-GP)可以解决 GAN 的一些稳定性…

【unity】认识unity Hub的主要功能

这里我们主要讲解unity Hub中的【项目】和【安装】功能&#xff0c;其他对应的功能栏相信大家根据文字就可以知道相应的作用。 首先是介绍【项目】功能&#xff0c;在这里我们可以创建本地项目和云端项目&#xff0c;作为初学者我们创建本地项目皆可&#xff0c;当然如果你是多…

UE4_碰撞_使用蓝图控制物体移动时如何让被阻挡

当我们这样设置蓝图时&#xff1a; 运行效果&#xff1a; 利用蓝图更改一个物体的位置&#xff0c;发现本来两个应该相互阻挡的物体被穿过去了。为了不让相互阻挡的物体被穿过去&#xff0c;我们需要设置好蓝图节点的参数Sweep。 勾选之后 墙的蓝图我们这样设置&#xff1a; 运…

【软件工程】需求分析

1. 导言 1.1. 需求文档的目的 该文档是关于用户对于“学生成绩管理系统”的功能和性能的要求&#xff0c;重点描述了“学生成绩管理系统”的设计需求&#xff0c;将作为对该工具在概要设计阶段的设计输入。编写本文档的目的在于说明软件工程管理系统的业务需求内容&#xff0…

30-3 越权漏洞 - 水平越权(横向越权)

环境准备:构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 一、定义 攻击者可以访问和操作与其拥有同级权限的用户资源。 示例: 学生A在教务系统上正常只能修改自己的作业内容,但由于不合理的权限校验规则等原因,学生A可以修改学生B的内…

记录C++中,vector的迭代器在push_back以后扩容导致迭代器失效的问题

前言 vector是我们用到最多的数据结构&#xff0c;其底层数据结构是单端动态数组&#xff0c;由于数组的特点&#xff0c;vector也具有以下特性&#xff1a; ①O(1)时间的快速访问&#xff1b; ②顺序存储&#xff0c;所以插入到非尾结点位置所需时间复杂度为O(n)&#xff0c;删…

uniapp开发微信小程序设置分包,简单易学

文章目录 前言一、在 manifest.json文件中的源码试图中配置二、配置pages.json 前言 我们使用uniapp开发微信小程序的时候&#xff0c;当我们的包体积过大的时候&#xff0c;无法真机模拟。 因为小程序单个包只支持2MB&#xff08;现已支持预览4MB&#xff09;&#xff0c;所以…

AI:155-基于深度学习的股票价格预测模型

本文收录于专栏:精通AI实战千例专栏合集 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 每一个案例都附带关键代码,详细讲解供大家学习,希望可以帮到大家。正在不断更新中~ 一.基于深度学习的股票价格预测模型 …

基于k8s的web服务器构建

文章目录 k8s综合项目1、项目规划图2、项目描述3、项目环境4、前期准备4.1、环境准备4.2、ip划分4.3、静态配置ip地址4.4、修改主机名4.5、部署k8s集群4.5.1、关闭防火墙和selinux4.5.2、升级系统4.5.3、每台主机都配置hosts文件&#xff0c;相互之间通过主机名互相访问4.5.4、…

总结IP协议各类知识点

前言 本篇博客博主将详解IP协议中的各类知识点&#xff0c;坐好板凳发车啦~ 一.IP协议格式 1.1 4位版本号&#xff08;version&#xff09; 指定IP协议的版本&#xff0c;对于IPv4来说&#xff0c;就是4。 1.2 4位头部长度&#xff08;header length&#xff09; IP头部的…

HarmonyOS像素转换-如何使用像素单位设置组件的尺寸。

1 卡片介绍 基于像素单位&#xff0c;展示了像素单位的基本知识与像素转换API的使用。 2 标题 像素转换&#xff08;ArkTS&#xff09; 3 介绍 本篇Codelab介绍像素单位的基本知识与像素单位转换API的使用。通过像素转换案例&#xff0c;向开发者讲解了如何使用像素单位设…

大数据-Hadoop---基础配置案例

VMware17创建新虚拟机&#xff1a; 1.静态设置与关闭防火墙 在终端命令行依次输入&#xff1a; 1&#xff09;cd /etc 2) ls 3) cd sysconfig/ 4) cd network-scripts/ 5) ls 6) vi ifcfg-nes33 在cmd命令栏输入&#xff1a;ncpa.cpl,是找网络适配器的命令 IPADDR&qu…

elementui el-input输入框类型为textarea时,将输入的数据保存换行和空格,并展示换行和空格

el-input输入框类型为textarea时&#xff0c;如果不做数据处理&#xff0c;是不会保存换行和空格的说输入了换行&#xff0c;但是保存数据后不会进行换行&#xff0c;需要保存输入的换行。 1、效果图 输入状态&#xff1a; 显示时&#xff1a; 2、实现代码 2.1、html部分&am…

在jupyter notebook中使用conda环境

在jupyter notebook中使用conda环境 1. 环境配置 conda activate my-conda-env # this is the environment for your project and code conda install ipykernel conda deactivateconda activate base # could be also some other environment conda install nb_cond…