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

news/2025/2/14 6:29:50/

(接上文《软件设计不是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.ppmy.cn/news/1400449.html

相关文章

3D产品可视化SaaS

“我们正在走向衰退吗&#xff1f;” “我们已经陷入衰退了吗&#xff1f;” “我们正在步入衰退。” 过去几个月占据头条的问题和陈述引发了关于市场对每个行业影响的讨论和激烈辩论。 特别是对于科技行业来说&#xff0c;过去几周一直很动荡&#xff0c;围绕费用、增长和裁…

vue/js总结合集

vuex的五大核心 内容作用映射位置调用其它state设置状态mapStatecomputedgetters获取内容mapGetterscomputed计算数据后返回mutations修改数据mapMutationsmethodscommit可以异步&#xff08;不建议&#xff09;不利于调试actions异步操作mapActionsmethodsdispatchmodules模块…

中国香港男歌手张国荣 明星网页成品 html人物明星网页设计制作 明星前端网页开发 网页期末设计制作作业成品

中国香港男歌手张国荣 7页面 人物明星主题 带设计说明 jquery图片轮播特效 滚动文字 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://ww…

【unity】unity安装及路线图

学习路线图 二、有关unity的下载 由于unity公司是在国外&#xff0c;所以.com版&#xff08;https://developer.unity.cn/&#xff09;不一定稳定&#xff0c;学习时推荐从.cn国内版&#xff08;https://developer.unity.cn/&#xff09;前往下载&#xff0c;但是后期仍需回…

题目 1414: 最大的字母

题目描述: 多组数据&#xff0c;每组输入一串字符串&#xff0c;对于输入的每个字符串&#xff0c;查找其中的最大字母&#xff0c;并在该字母后面插入字符串“(DJTU)”。 代码: package lanqiao;import java.util.*; public class Main {public static void main(String[] …

vue3-pinia使用(末尾有彩蛋)

什么是 pinia Pinia 是 Vue 的专属状态管理库&#xff0c;它允许你跨组件或页面共享状态。 之前用的是 vuex&#xff0c;后面 vue 官方团队不维护了&#xff0c;推荐使用 pinia 安装 yarn add pinia # 或者使用 npm npm install piniapnpm install piniaStore 是什么&#xf…

ATTCK学习笔记

ATT&CK 前言知识 威胁情报&#xff1a;一般为网络流量中或者操作系统上观察到的能高度表明计算机被入侵的痕迹&#xff0c;例如某病毒的Hash值、服务器的IP地址等等。简单来说&#xff0c;威胁情报就像是当计算机被入侵时所表现出来的某种特征&#xff0c;我们将这些威胁…

Spark-Scala语言实战(7)

在之前的文章中&#xff0c;我们学习了如何在IDEA中导入jars包&#xff0c;并做了一道例题&#xff0c;了解了RDD。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢…