资讯详情

CodeGuide 实战解析:用状态模式重构营销活动审核状态流转,告别 ifelse

📅 2026/9/24 16:23:32 | 华诺云谱 👁 阅读
CodeGuide 实战解析:用状态模式重构营销活动审核状态流转,告别 ifelse
文档教程后端【免费下载链接】CodeGuide:books: 本代码库是作者小傅哥多年从事一线互联网 Java 开发的学习历程技术汇总旨在为大家提供一个清晰详细的学习教程侧重点更倾向编写Java核心内容。如果本仓库能为您提供帮助请给予支持(关注、点赞、分享)项目地址https://gitcode.com/gh_mirrors/code/CodeGuide点击查看免费下载本文以 CodeGuide 仓库《重学 Java 设计模式》系列中的状态模式章节为主体以系统营销活动审核发布上线这一真实业务场景为骨架完整讲解状态模式的核心思想、基于 ifelse 的原始实现、以及基于接口 抽象类 状态机映射的状态模式重构方案并通过多组单元测试验证状态流转的合法性。读完本文你将掌握如何用状态模式消除多分支状态判断、如何设计State抽象类与StateHandler状态处理器以及判断什么场景值得引入状态模式的权衡方法。一、状态模式介绍行为随状态而变状态模式State Pattern描述的是一种行为下的多种状态变更。它允许一个对象在其内部状态改变时改变它的行为对象看起来像是修改了它的类。举一个最常见的生活化例子网站的页面在你登录与不登录两种状态下展示的内容是略有差异的——不登录不能展示个人信息。这种登录 / 不登录就是通过改变状态让整个页面的行为发生了变化。再比如 80 后、90 后都用过的磁带放音机放入磁带后通过机器上的一排按钮可以让放音机播放磁带内容而且有些按钮是互斥的——只有在某个状态下才可以按另外的按钮。这种不同状态下可执行的操作不同的约束正是状态模式要解决的核心问题。对应到代码设计上状态模式把某个状态能做什么、不能做什么从大段的判断逻辑中抽离出来交给一个个独立的状态实现类去表达从而让状态流转规则变得清晰、可扩展、可维护。二、案例场景模拟营销活动审核状态流转在本案例中我们模拟一个营销活动审核状态流转场景——一个活动的上线需要经过多个层级的审核。流程节点中包括各个状态到下一个状态扭转的关联条件例如只有审核通过才能进入活动中而不能从编辑中直接到活动中。这些状态之间的转变就是本案例要完成的场景处理。大部分程序员基本都开发过类似的业务场景对活动或一些配置需要审核后才能对外发布而这个审核的过程往往会随着系统的重要程度而设立多级控制来保证一个活动可以安全上线避免造成资损。当然有时也会使用到一些审批流的配置来方便开发可以在配置中设定某个节点的审批人员但这并不是本案例要体现的重点——本案例主要模拟学习对一个活动的多个状态节点的审核控制。在本仓库中本文属于 《重学 Java 设计模式》系列 中的一节与工厂方法模式、策略模式、模板模式等同属一个完整的实战教学体系该系列图书信息可参考 《重学Java设计模式》书籍介绍。1. 场景模拟工程结构围绕这个场景原文搭建了一个场景模拟工程工程结构如下itstack-demo-design-19-00 └── src └── main └── java └── org.itstack.demo.design ├── ActivityInfo.java ├── Status.java └── ActivityService.java在这个模拟工程里提供了三个类状态枚举Status、活动对象ActivityInfo、活动服务ActivityService。2. 基本活动信息public class ActivityInfo { private String activityId; // 活动ID private String activityName; // 活动名称 private EnumStatus status; // 活动状态 private Date beginTime; // 开始时间 private Date endTime; // 结束时间 // ...get/set }这是一些基本的活动信息活动 ID、活动名称、活动状态、开始时间、结束时间。3. 活动枚举状态public enum Status { // 1创建编辑、2待审核、3审核通过(任务扫描成活动中)、4审核拒绝(可以撤审到编辑状态)、5活动中、6活动关闭、7活动开启(任务扫描成活动中) Editing, Check, Pass, Refuse, Doing, Close, Open }活动的枚举共 7 个状态对应含义如下枚举值状态含义说明Editing创建编辑活动初始状态Check待审核编辑后提交审核Pass审核通过由任务扫描成活动中Refuse审核拒绝可以撤审回到编辑状态Doing活动中活动正在执行Close活动关闭关闭后不可直接开启Open活动开启由任务扫描成活动中4. 活动服务接口public class ActivityService { private static MapString, EnumStatus statusMap new ConcurrentHashMapString, EnumStatus(); public static void init(String activityId, EnumStatus status) { // 模拟查询活动信息 ActivityInfo activityInfo new ActivityInfo(); activityInfo.setActivityId(activityId); activityInfo.setActivityName(早起学习打卡领奖活动); activityInfo.setStatus(status); activityInfo.setBeginTime(new Date()); activityInfo.setEndTime(new Date()); statusMap.put(activityId, status); } /** * 查询活动信息 * * param activityId 活动ID * return 查询结果 */ public static ActivityInfo queryActivityInfo(String activityId) { // 模拟查询活动信息 ActivityInfo activityInfo new ActivityInfo(); activityInfo.setActivityId(activityId); activityInfo.setActivityName(早起学习打卡领奖活动); activityInfo.setStatus(statusMap.get(activityId)); activityInfo.setBeginTime(new Date()); activityInfo.setEndTime(new Date()); return activityInfo; } /** * 查询活动状态 * * param activityId 活动ID * return 查询结果 */ public static EnumStatus queryActivityStatus(String activityId) { return statusMap.get(activityId); } /** * 执行状态变更 * * param activityId 活动ID * param beforeStatus 变更前状态 * param afterStatus 变更后状态 */ public static synchronized void execStatus(String activityId, EnumStatus beforeStatus, EnumStatus afterStatus) { if (!beforeStatus.equals(statusMap.get(activityId))) return; statusMap.put(activityId, afterStatus); } }在这个静态类中提供了活动的查询和状态变更接口queryActivityInfo、queryActivityStatus、execStatus。同时使用Map结构来记录活动 ID 和状态变化信息另外还有init方法来初始化活动数据。需要说明的是这里为了便于演示使用了内存 Map 模拟数据存储实际的开发中这类信息基本都是从数据库或者Redis中获取execStatus方法使用synchronized保证状态变更的原子性并做了前置状态校验beforeStatus必须与当前存储状态一致才允许变更这本身就是一个轻量级的乐观校验。三、用一坨坨代码实现ifelse 的代价这里先使用最粗暴的方式来实现功能。对于这样各种状态的变更最直接想到的就是使用if和else进行判断处理。每一个状态可以流转到下一个什么状态都可以使用嵌套的if实现。1. 工程结构itstack-demo-design-19-01 └── src └── main └── java └── org.itstack.demo.design ├── ActivityExecStatusController.java └── Result.java整个实现的工程结构比较简单只包括了两个类ActivityExecStatusController处理流程状态、Result返回结果对象。2. 代码实现整篇 ifelsepublic class ActivityExecStatusController { /** * 活动状态变更 * 1. 编辑中 - 提审、关闭 * 2. 审核通过 - 拒绝、关闭、活动中 * 3. 审核拒绝 - 撤审、关闭 * 4. 活动中 - 关闭 * 5. 活动关闭 - 开启 * 6. 活动开启 - 关闭 * * param activityId 活动ID * param beforeStatus 变更前状态 * param afterStatus 变更后状态 * return 返回结果 */ public Result execStatus(String activityId, EnumStatus beforeStatus, EnumStatus afterStatus) { // 1. 编辑中 - 提审、关闭 if (Status.Editing.equals(beforeStatus)) { if (Status.Check.equals(afterStatus) || Status.Close.equals(afterStatus)) { ActivityService.execStatus(activityId, beforeStatus, afterStatus); return new Result(0000, 变更状态成功); } else { return new Result(0001, 变更状态拒绝); } } // 2. 审核通过 - 拒绝、关闭、活动中 if (Status.Pass.equals(beforeStatus)) { if (Status.Refuse.equals(afterStatus) || Status.Doing.equals(afterStatus) || Status.Close.equals(afterStatus)) { ActivityService.execStatus(activityId, beforeStatus, afterStatus); return new Result(0000, 变更状态成功); } else { return new Result(0001, 变更状态拒绝); } } // 3. 审核拒绝 - 撤审、关闭 if (Status.Refuse.equals(beforeStatus)) { if (Status.Editing.equals(afterStatus) || Status.Close.equals(afterStatus)) { ActivityService.execStatus(activityId, beforeStatus, afterStatus); return new Result(0000, 变更状态成功); } else { return new Result(0001, 变更状态拒绝); } } // 4. 活动中 - 关闭 if (Status.Doing.equals(beforeStatus)) { if (Status.Close.equals(afterStatus)) { ActivityService.execStatus(activityId, beforeStatus, afterStatus); return new Result(0000, 变更状态成功); } else { return new Result(0001, 变更状态拒绝); } } // 5. 活动关闭 - 开启 if (Status.Close.equals(beforeStatus)) { if (Status.Open.equals(afterStatus)) { ActivityService.execStatus(activityId, beforeStatus, afterStatus); return new Result(0000, 变更状态成功); } else { return new Result(0001, 变更状态拒绝); } } // 6. 活动开启 - 关闭 if (Status.Open.equals(beforeStatus)) { if (Status.Close.equals(afterStatus)) { ActivityService.execStatus(activityId, beforeStatus, afterStatus); return new Result(0000, 变更状态成功); } else { return new Result(0001, 变更状态拒绝); } } return new Result(0001, 非可处理的活动状态变更); } }从代码结构可以看出从上到下是一整篇的ifelse这也是大部分初级程序员的开发方式。综合来看这套代码中的状态流转规则是编辑中 → 提审、关闭审核通过 → 拒绝、关闭、活动中审核拒绝 → 撤审、关闭活动中 → 关闭活动关闭 → 开启活动开启 → 关闭这样的面向过程式开发方式对于不需要改动代码、也不需要二次迭代的场景还是可以使用的但基本不可能不迭代。随着状态和需求的变化这套代码会越来越难以维护每增加一个状态就要在ifelse链条中再插入一段判断后来的人不好看懂也很容易填充其他流程进去。越来越乱就是从点滴开始的。3. 测试验证 ifelse 实现3.1 编写测试类Test public void test() { // 初始化数据 String activityId 100001; ActivityService.init(activityId, Status.Editing); ActivityExecStatusController activityExecStatusController new ActivityExecStatusController(); Result resultRefuse activityExecStatusController.execStatus(activityId, Status.Editing, Status.Refuse); logger.info(测试结果(编辑中To审核拒绝){}, JSON.toJSONString(resultRefuse)); Result resultCheck activityExecStatusController.execStatus(activityId, Status.Editing, Status.Check); logger.info(测试结果(编辑中To提交审核){}, JSON.toJSONString(resultCheck)); }测试代码包括两个功能的验证一个是从编辑中到审核拒绝另外一个是从编辑中到提交审核。因为从场景流程中可以看到编辑中的活动是不能直接到审核拒绝的这中间还需要提审。3.2 测试结果23:24:30.774 [main] INFO org.itstack.demo.design.test.ApiTest - 测试结果(编辑中To审核拒绝){code:0001,info:变更状态拒绝} 23:24:30.778 [main] INFO org.itstack.demo.design.test.ApiTest - 测试结果(编辑中To提交审核){code:0000,info:变更状态成功} Process finished with exit code 0从测试结果和状态流程的流转中可以确认结果是符合预期的。除了不好维护外这样的开发过程还是蛮快的但不建议这么搞四、状态模式重构代码让状态自己管自己接下来使用状态模式来进行代码优化也算是一次很小的重构。重构的重点往往是处理掉ifelse而想处理掉ifelse基本离不开接口与抽象类另外还需要重新改造代码结构。1. 工程结构itstack-demo-design-19-02 └── src └── main └── java └── org.itstack.demo.design ├── event │ ├── CheckState.java │ ├── CloseState.java │ ├── DoingState.java │ ├── EditingState.java │ ├── OpenState.java │ ├── PassState.java │ └── RefuseState.java ├── Result.java ├── State.java └── StateHandler.java状态模式模型结构State是一个抽象类定义了各种操作接口提审、审核、拒审等右侧的 7 个状态实现类与场景中的状态一一对应是各种状态流转的实现操作。这里实现的关键点在于每一种状态到下一个状态都分配到各个实现方法中控制也就不需要if语言进行判断了。最后是StateHandler对状态流程的统一处理内部提供Map结构的各项服务接口调用也就避免了使用if判断各项状态转变的流程。2. 定义状态抽象类public abstract class State { /** * 活动提审 * * param activityId 活动ID * param currentStatus 当前状态 * return 执行结果 */ public abstract Result arraignment(String activityId, EnumStatus currentStatus); /** * 审核通过 * * param activityId 活动ID * param currentStatus 当前状态 * return 执行结果 */ public abstract Result checkPass(String activityId, EnumStatus currentStatus); /** * 审核拒绝 * * param activityId 活动ID * param currentStatus 当前状态 * return 执行结果 */ public abstract Result checkRefuse(String activityId, EnumStatus currentStatus); /** * 撤审撤销 * * param activityId 活动ID * param currentStatus 当前状态 * return 执行结果 */ public abstract Result checkRevoke(String activityId, EnumStatus currentStatus); /** * 活动关闭 * * param activityId 活动ID * param currentStatus 当前状态 * return 执行结果 */ public abstract Result close(String activityId, EnumStatus currentStatus); /** * 活动开启 * * param activityId 活动ID * param currentStatus 当前状态 * return 执行结果 */ public abstract Result open(String activityId, EnumStatus currentStatus); /** * 活动执行 * * param activityId 活动ID * param currentStatus 当前状态 * return 执行结果 */ public abstract Result doing(String activityId, EnumStatus currentStatus); }在整个接口中提供了各项状态流转服务的抽象方法例如活动提审、审核通过、审核拒绝、撤审撤销等 7 个方法。在这些方法中所有的入参都是一样的——activityId活动ID、currentStatus当前状态——只有它们的具体实现是不同的。这样一来状态流转的合法性规则被下沉到了每个状态实现类内部天然形成了该状态允许哪些操作、拒绝哪些操作的边界。3. 部分状态流转实现编辑状态EditingStatepublic class EditingState extends State { public Result arraignment(String activityId, EnumStatus currentStatus) { ActivityService.execStatus(activityId, currentStatus, Status.Check); return new Result(0000, 活动提审成功); } public Result checkPass(String activityId, EnumStatus currentStatus) { return new Result(0001, 编辑中不可审核通过); } public Result checkRefuse(String activityId, EnumStatus currentStatus) { return new Result(0001, 编辑中不可审核拒绝); } Override public Result checkRevoke(String activityId, EnumStatus currentStatus) { return new Result(0001, 编辑中不可撤销审核); } public Result close(String activityId, EnumStatus currentStatus) { ActivityService.execStatus(activityId, currentStatus, Status.Close); return new Result(0000, 活动关闭成功); } public Result open(String activityId, EnumStatus currentStatus) { return new Result(0001, 非关闭活动不可开启); } public Result doing(String activityId, EnumStatus currentStatus) { return new Result(0001, 编辑中活动不可执行活动中变更); } }提审状态CheckStatepublic class CheckState extends State { public Result arraignment(String activityId, EnumStatus currentStatus) { return new Result(0001, 待审核状态不可重复提审); } public Result checkPass(String activityId, EnumStatus currentStatus) { ActivityService.execStatus(activityId, currentStatus, Status.Pass); return new Result(0000, 活动审核通过完成); } public Result checkRefuse(String activityId, EnumStatus currentStatus) { ActivityService.execStatus(activityId, currentStatus, Status.Refuse); return new Result(0000, 活动审核拒绝完成); } Override public Result checkRevoke(String activityId, EnumStatus currentStatus) { ActivityService.execStatus(activityId, currentStatus, Status.Editing); return new Result(0000, 活动审核撤销回到编辑中); } public Result close(String activityId, EnumStatus currentStatus) { ActivityService.execStatus(activityId, currentStatus, Status.Close); return new Result(0000, 活动审核关闭完成); } public Result open(String activityId, EnumStatus currentStatus) { return new Result(0001, 非关闭活动不可开启); } public Result doing(String activityId, EnumStatus currentStatus) { return new Result(0001, 待审核活动不可执行活动中变更); } }这里提供了两个具体实现类编辑状态和提审状态。可以看到同一个checkRefuse方法在编辑状态下返回编辑中不可审核拒绝而在提审状态下则执行状态流转返回活动审核拒绝完成——这就是不同状态下能做的下一步流转操作可以在每一个方法中具体控制的直接体现。其余 5 个状态实现类CloseState、DoingState、OpenState、PassState、RefuseState的操作是类似的大部分是重复代码遵循同样的允许流转则调用ActivityService.execStatus并返回成功不允许流转则直接返回拒绝模式可以通过源码学习理解。4. 状态处理服务StateHandlerpublic class StateHandler { private MapEnumStatus, State stateMap new ConcurrentHashMapEnumStatus, State(); public StateHandler() { stateMap.put(Status.Check, new CheckState()); // 待审核 stateMap.put(Status.Close, new CloseState()); // 已关闭 stateMap.put(Status.Doing, new DoingState()); // 活动中 stateMap.put(Status.Editing, new EditingState()); // 编辑中 stateMap.put(Status.Open, new OpenState()); // 已开启 stateMap.put(Status.Pass, new PassState()); // 审核通过 stateMap.put(Status.Refuse, new RefuseState()); // 审核拒绝 } public Result arraignment(String activityId, EnumStatus currentStatus) { return stateMap.get(currentStatus).arraignment(activityId, currentStatus); } public Result checkPass(String activityId, EnumStatus currentStatus) { return stateMap.get(currentStatus).checkPass(activityId, currentStatus); } public Result checkRefuse(String activityId, EnumStatus currentStatus) { return stateMap.get(currentStatus).checkRefuse(activityId, currentStatus); } public Result checkRevoke(String activityId, EnumStatus currentStatus) { return stateMap.get(currentStatus).checkRevoke(activityId, currentStatus); } public Result close(String activityId, EnumStatus currentStatus) { return stateMap.get(currentStatus).close(activityId, currentStatus); } public Result open(String activityId, EnumStatus currentStatus) { return stateMap.get(currentStatus).open(activityId, currentStatus); } public Result doing(String activityId, EnumStatus currentStatus) { return stateMap.get(currentStatus).doing(activityId, currentStatus); } }StateHandler是状态服务的统一控制中心在构造函数中建立了所有状态枚举到具体状态实现类的映射关系放到Map数据结构中使用ConcurrentHashMap保证并发安全。同时提供不同名称的接口操作类让外部调用方可以更加容易地使用功能接口——调用方只需要传入activityId和currentStatus而不需要像ifelse版本那样传两个状态来判断。这个Map映射正是状态模式的查表替代分支核心状态流转规则不再散落在 ifelse 链中而是集中收敛在状态 → 状态实现类的一张表 每个实现类内部的 7 个方法里。新增一个状态只需新增一个State子类并注册进stateMap无需改动任何已有状态类符合开闭原则。五、状态模式重构后的测试验证1. 测试类一编辑中 → 提审合法流转Test public void test_Editing2Arraignment() { String activityId 100001; ActivityService.init(activityId, Status.Editing); StateHandler stateHandler new StateHandler(); Result result stateHandler.arraignment(activityId, Status.Editing); logger.info(测试结果(编辑中To提审活动){}, JSON.toJSONString(result)); logger.info(活动信息{} 状态{}, JSON.toJSONString(ActivityService.queryActivityInfo(activityId)), JSON.toJSONString(ActivityService.queryActivityInfo(activityId).getStatus())); }测试结果23:59:20.883 [main] INFO org.itstack.demo.design.test.ApiTest - 测试结果(编辑中To提审活动){code:0000,info:活动提审成功} 23:59:20.907 [main] INFO org.itstack.demo.design.test.ApiTest - 活动信息{activityId:100001,activityName:早起学习打卡领奖活动,beginTime:1593694760892,endTime:1593694760892,status:Check} 状态Check Process finished with exit code 0测试编辑中 → 提审活动状态由Editing合法流转为Check。2. 测试类二编辑中 → 开启非法流转Test public void test_Editing2Open() { String activityId 100001; ActivityService.init(activityId, Status.Editing); StateHandler stateHandler new StateHandler(); Result result stateHandler.open(activityId, Status.Editing); logger.info(测试结果(编辑中To开启活动){}, JSON.toJSONString(result)); logger.info(活动信息{} 状态{}, JSON.toJSONString(ActivityService.queryActivityInfo(activityId)), JSON.toJSONString(ActivityService.queryActivityInfo(activityId).getStatus())); }测试结果23:59:36.904 [main] INFO org.itstack.demo.design.test.ApiTest - 测试结果(编辑中To开启活动){code:0001,info:非关闭活动不可开启} 23:59:36.914 [main] INFO org.itstack.demo.design.test.ApiTest - 活动信息{activityId:100001,activityName:早起学习打卡领奖活动,beginTime:1593694776907,endTime:1593694776907,status:Editing} 状态Editing Process finished with exit code 0测试编辑中 → 开启活动EditingState.open直接返回拒绝状态保持不变证明非法流转被有效拦截。3. 测试类三拒绝 → 活动中非法流转Test public void test_Refuse2Doing() { String activityId 100001; ActivityService.init(activityId, Status.Refuse); StateHandler stateHandler new StateHandler(); Result result stateHandler.doing(activityId, Status.Refuse); logger.info(测试结果(拒绝To活动中){}, JSON.toJSONString(result)); logger.info(活动信息{} 状态{}, JSON.toJSONString(ActivityService.queryActivityInfo(activityId)), JSON.toJSONString(ActivityService.queryActivityInfo(activityId).getStatus())); }测试结果23:59:46.339 [main] INFO org.itstack.demo.design.test.ApiTest - 测试结果(拒绝To活动中){code:0001,info:审核拒绝不可执行活动为进行中} 23:59:46.352 [main] INFO org.itstack.demo.design.test.ApiTest - 活动信息{activityId:100001,activityName:早起学习打卡领奖活动,beginTime:1593694786342,endTime:1593694786342,status:Refuse} 状态Refuse Process finished with exit code 0测试拒绝 → 活动中被RefuseState.doing拦截证明审核被拒绝的活动不能直接进入进行中状态。4. 测试类四拒绝 → 撤审合法流转Test public void test_Refuse2Revoke() { String activityId 100001; ActivityService.init(activityId, Status.Refuse); StateHandler stateHandler new StateHandler(); Result result stateHandler.checkRevoke(activityId, Status.Refuse); logger.info(测试结果(拒绝To撤审){}, JSON.toJSONString(result)); logger.info(活动信息{} 状态{}, JSON.toJSONString(ActivityService.queryActivityInfo(activityId)), JSON.toJSONString(ActivityService.queryActivityInfo(activityId).getStatus())); }测试结果23:59:50.197 [main] INFO org.itstack.demo.design.test.ApiTest - 测试结果(拒绝To撤审){code:0000,info:撤销审核完成} 23:59:50.208 [main] INFO org.itstack.demo.design.test.ApiTest - 活动信息{activityId:100001,activityName:早起学习打卡领奖活动,beginTime:1593694810201,endTime:1593694810201,status:Editing} 状态Editing Process finished with exit code 0测试拒绝 → 撤审状态由Refuse合法流转回Editing。综上以上四个测试类分别模拟了不同状态之间的有效流转和拒绝流转不同的状态服务处理不同的服务内容。这组测试也印证了状态模式重构后的可验证性每一个状态 × 操作组合的行为都是确定且可独立测试的这是面向过程 ifelse 版本难以做到的。六、总结与适用边界从以上两种方式对同一个需求的实现可以看到在使用状态模式处理后消灭了 ifelse代码中已经没有了多层嵌套的状态判断代码的结构更加清晰、易于扩展。状态流转的合法性从调用方的判断迁移到了状态实现类自身的约束职责更加内聚。从面向过程走向面向对象实现结构上不再是面向过程的编程而是面向对象的结构。这样的设计模式满足了单一职责原则每个状态类只负责自身状态的流转规则和开闭原则新增状态只需新增子类并注册无需修改已有类只有满足这样的结构下才会发现代码的扩展是容易的——增加和修改功能不会影响整体的变化。权衡成本如果状态和各项流转较多像本文案例中就会产生较多的实现类因此可能会带来代码实现上的时间成本。遇到这样的场景可以按需评估投入产出比主要判断点在于是否经常修改、是否可以做成组件化、能否抽离业务与非业务功能。对于类似多层级审核上线订单状态机审批流这类状态多、流转规则复杂且频繁迭代的业务场景状态模式是值得优先考虑的重构方案而如果状态极少且规则几乎不变则可以权衡是否值得引入较多的实现类。本案例完整的代码结构、类图与测试用例可结合 CodeGuide 仓库 中《重学 Java 设计模式》系列的其余篇章如责任链模式、命令模式对照学习理解不同模式在消除条件分支时的不同切入角度。赞分享文档教程后端【免费下载链接】CodeGuide:books: 本代码库是作者小傅哥多年从事一线互联网 Java 开发的学习历程技术汇总旨在为大家提供一个清晰详细的学习教程侧重点更倾向编写Java核心内容。如果本仓库能为您提供帮助请给予支持(关注、点赞、分享)项目地址https://gitcode.com/gh_mirrors/code/CodeGuide点击查看免费下载相关推荐itstack-demo-design状态模式活动生命周期管理实战状态机让状态流转不再靠硬编码itstack demo design状态模式活动生命周期管理实战状态机让状态流转不再靠硬编码 在《重学Java设计模式》实战项目 itstack demo示例工程教程告别状态混乱Temporal工作流状态管理实战指南告别状态混乱Temporal工作流状态管理实战指南 你是否还在为复杂业务流程中的状态同步而头疼订单处理中断、数据不一致、重试逻辑混乱本文将带你了解Temp后端工作流自动化任务调度CANN/GE图引擎UpdateOutputDesc函数UpdateOutputDesca nameZH CN_TOPIC_0000002484276834 /a 产品支持情况a namesectio人工智能深度学习模型编译模型优化编译器Ascend上一篇摄影工作流革命semi-utils批量水印工具的完整解决方案下一篇Monitorian如何优雅管理Windows多显示器亮度控制创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。