转载自:https://blog.csdn.net/weixin_39631301/article/details/112082970

流程编排

随着业务的不断发展,业务流程迭代慢慢变得复杂了起来,全景不清晰,这不仅仅会使开发人员编写代码弄的’ 不敢改 '心理,以及出现问题不好寻找出错位置,历史包袱太重,影响面需要评估,等等。
一个本来很简单的需求,但是由于很多历史背景和包袱导致侵入代码需要评估改动影响面很大,这时候就需要一套流程编排来使得流程清晰,能全局感受到业务的能力地图。减少开发、测试等的维护迭代成本。

流程编排特点

流程配置化

通过配置化的方式形成业务规则,通过插拔某些组件形成新的规则,每条规则对应一个业务身份(比如,“餐饮商品下单”就是一个业务身份),当我们需要新增业务身份,其实就是在对能力进行聚合编排,最终配置成我们需要的业务规则。

能力复用

在更多的业务身份产生的同时,更多的业务能力也被我们沉淀下来,能力会被编排进更多的业务规则中,在各个规则中复用。

业务细节聚合

在传统模式中,随着需求的不断迭代以及开发人员不同的编码习惯,越来越多的业务逻辑被分散在各个代码模块,给后续业务的理解和迭代造成很大的困难,而通过流程编排,不同的能力被分组聚合,各个能力职责单一,校验只做校验,装配只做装配。

通过执行引擎,实现技术细节和业务逻辑的分离

开发人员只需要定规则,具体的执行完全由执行引擎调度,强大的执行引擎通过其本身复杂的实现而让开发者获得更好的编码体验,如跨组件事务,依赖注入,监控等。

流程编排组件

参数校验 – 业务校验 – 事务前置扩展点 – 业务参数装配 – 事务执行 – 事务结果装配 – 事务后置扩展点
备注:节点不固定,根本具体业务评估需要哪些组件。

流程编排实现

下面我们就简单实现一个demo级的流程编排例子。
能力流程编排的各个组件我们通过上下文使它们环环相扣,定义如下:

package com.orangecsong.st.template;import java.io.Serializable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** @Description: 上下文* @author: orangeCs* @create: 2020-08-22*/
public class Context implements Serializable {private final Map<Class<?>,Object> CONTEXT = new ConcurrentHashMap<>();public <T> T get(Class<T> clazz) {return (T) CONTEXT.get(clazz);}public void put(Object obj) {if(null == obj) {return;}CONTEXT.put(obj.getClass(),obj);}
}

事务执行模板,定义组件之间api,为了通用,我们这里将上下文注射到回调模板的泛型参数中

package com.orangecsong.st.template;import com.orangecsong.bizclass.BaseResult;/*** @Description: 流程引擎-执行事件接口* @author: orangeCs* @create: 2020-08-22*/
public interface ActionCallBack<T extends BaseResult, C extends Context> {void paramValidate(C context);void bizValidate(C context);void beforeProcess(C context);void process(C context);void afterProcess(C context);T assemble(C context);
}

考虑到某些业务无需扩展点交互,为此我们抽象出来。

package com.orangecsong.st.template;import com.orangecsong.bizclass.BaseResult;/*** @Description: 流程引擎-抽象执行事件接口* @author: orangeCs* @create: 2020-08-22*/
public abstract class AbstractActionCallBack<T extends BaseResult,C extends Context> implements ActionCallBack<T,C>{@Overridepublic void beforeProcess(C context) {}@Overridepublic void afterProcess(C context) {}
}

接下来我们定义流程引擎具体实现类

package com.orangecsong.st.template;import com.orangecsong.bizclass.BaseResult;/*** @Description: 通用的执行器* @author: orangeCs* @create: 2020-08-22*/
public class GeneralActionCallBack extends AbstractActionCallBack<BaseResult,Context> {@Overridepublic void paramValidate(Context context) {}@Overridepublic void bizValidate(Context context) {}@Overridepublic void process(Context context) {}@Overridepublic BaseResult assemble(Context context) {return null;}
}

为了业务流程中调用,我们封装对外调用API ,传入对应上下文、回调函数即可。

package com.orangecsong.st.template;import com.orangecsong.bizclass.BaseResult;/*** @Description:* @author: orangeCs* @create: 2020-08-22*/
public interface ServiceTemplate<T extends BaseResult,C extends Context> {/*** @param context* @param action* @return*/T invoke(C context, AbstractActionCallBack<T, C> action);
}

对业务无感知的流程引擎实现

package com.orangecsong.st.template;import com.orangecsong.bizclass.BaseResult;/*** @Description: 服务模板* @author: orangeCs* @create: 2020-08-22*/
public class ServiceTemplateImpl implements ServiceTemplate{@Overridepublic BaseResult invoke(Context context, AbstractActionCallBack action) {//参数校验paramValidate(context, action);//业务校验bizValidate(context, action);//事务执行前置扩展点beforeProcessCallBack(context, action);//事务执行processCallBack(context, action);//事务执行后置扩展点afterProcessCallBack(context, action);//数据装配return assemble(context, action);}private BaseResult assemble (Context context, AbstractActionCallBack action){System.out.println("assemble");return action.assemble(context);}private void afterProcessCallBack (Context context, AbstractActionCallBack action){System.out.println("afterProcessCallBack");action.afterProcess(context);}private void processCallBack (Context context, AbstractActionCallBack action){System.out.println("processCallBack");action.process(context);}private void beforeProcessCallBack (Context context, AbstractActionCallBack action){System.out.println("beforeProcessCallBack");action.beforeProcess(context);}private void bizValidate (Context context, AbstractActionCallBack action){System.out.println("bizValidate");action.bizValidate(context);}private void paramValidate (Context context, AbstractActionCallBack action){System.out.println("paramValidate");action.paramValidate(context);}
}

最后我们写个测试程序测试一下

package com.orangecsong.st.client;import com.orangecsong.bizclass.BaseResult;
import com.orangecsong.st.template.Context;
import com.orangecsong.st.template.ServiceTemplate;
import com.orangecsong.st.template.ServiceTemplateImpl;/*** @Description: 测试服务模板流程引擎调用* @author: orangeCs* @create: 2020-08-22* <pre>*     查询学生为某某某的人*     paramValidate 学生id不能为空 且大于0*     bizValidate 学生姓名不能带“cute”*     process 查询db 得到结果* </pre>*/
public class ServiceTemplateInvoke {public static void main(String[] args) {//构造上下文Context context = new Context();context.put(10);StudentAction studentAction = new StudentAction();ServiceTemplate serviceTemplate = new ServiceTemplateImpl();final BaseResult invoke = serviceTemplate.invoke(context, studentAction);System.out.println(invoke.getData());}
}

最后强调一下,任务技术的引入都是一把双刃剑,我们还是需要根据具体的场景和业务评估采取哪种方式,如果业务简单,流程不复杂,我们引入了流程引擎,一是增加了对流程引擎使用了解的成本,二是杀鸡用牛刀,工具的使用宗旨是让我们处理高效。

java流程引擎实现_手写实现一套流程编排相关推荐

  1. 手写数字识别整体流程

    手写数字识别整体流程 pytorch中数据加载 batch:数据打乱顺序,组成一波-波的数据,批处理 epoch:拿所有的数据训练一-次 Dataset基类,数据集类 torch.utils.data ...

  2. 使用java语言基于SMTP协议手写邮件客户端

    使用java语言基于SMTP协议手写邮件客户端 1. 说明 电子邮件是互联网上常见的应用,他是互联网早期的产品,直至今日依然受到广大用户的喜爱(在中国可能因为文化背景不同,电子邮件只在办公的时候常用) ...

  3. java linkedlist底层_手写Java LinkedList核心源码

    上一章我们手写了ArrayList的核心源码,ArrayList底层是用了一个数组来保存数据,数组保存数据的优点就是查找效率高,但是删除效率特别低,最坏的情况下需要移动所有的元素.在查找需求比较重要的 ...

  4. java实现手写签名_手写签字,保存笔迹到图片

    [实例简介] [实例截图] [核心代码] package cn.handwriting; import java.io.ByteArrayOutputStream; import java.io.Fi ...

  5. java手写识别_手写识别系统

    目的 采用k-近邻算法实现手写识别系统.这里采用0和1组成数字0-9的形状,再用算法对这些形状进行识别,来分辨出形状属于0-9那个数字.并计算出k-近邻算法识别手写数字的错误率. 数据说明 数据来自& ...

  6. Java txt 下拉刷新_手写上拉加载,下拉刷新(小demo)

    背景 使用过很多下拉刷新,上拉加载的插件,虽然也知道一点原理,但似乎一直不太完全能理解它,闲来无事,手写一个,感受下,借鉴了better-scroll的源码,功能当然相差甚远,也只是个简易版的实现,大 ...

  7. redis setnx 分布式锁_手写Redis分布式锁

    分布式锁使用场景 现在的系统都是集群部署,每个服务都不是单节点的了.比如库存服务,可能部署到3台机器上分别命名为节点1,节点2,节点3.库存服务需要扣减库存,扣减库存肯定需要锁吧,如果使用Lock或者 ...

  8. c++socket多个客户端通过不同端口与一个服务端通信_手写RPC,深入底层理解整个RPC通信...

    一.前言 RPC,远程过程调用,调用远程方法像调用本地方法一样.RPC交互分为客户端和服务端,客户端调用服务端方法,服务端接收数据并打印到控制台,并response响应给客户端. RPC和HTTP的联 ...

  9. js如何在当前页面加载springmvc返回的页面_手写SpringMVC学习

    前面我们学习了spring框架源码,做了一些自己手写的学习,最近,我们开始学习springMVC框架的学习 ,springMVC框架,相信大家不陌生了,所以这里不做过多的介绍了. SpringMVC以 ...

最新文章

  1. 解读基于多传感器融合的卡尔曼滤波算法
  2. USB HID report descriptor
  3. python hook技术,python hook监听事件详解
  4. Arthas 使用的四种方式
  5. 01-Flutter移动电商实战-项目学习记录
  6. 行为模型:客户行为智能分析模型
  7. JavaScript技巧[转载]
  8. matlab 元胞数组合并(fail)
  9. 自创算法实现Reporting Service中多值判定
  10. 面向对象之自动生成助记码
  11. android呼叫转移代码,动态Android呼叫转移
  12. 第一行输入一个正整数N,随后的N行各输入一个人的姓名和年龄,中间用空格分隔(形如 “Tom 18“),将字符串转为形如 {“name“:“Tom“,“age“:18} 的字典,按顺序加入到列表中,得到
  13. 现在移动端还用rem吗?nonono
  14. 大话谈VUE之export const
  15. package.json bin的作用
  16. 超低延时的H5直播,电子游戏互动控制直播,桌面远程控制直播方案
  17. Apache Flink源码阅读环境搭建
  18. 港科夜闻|香港科大海洋科学系主任兼讲座教授钱培元:成立产业推广部抢商机...
  19. 书评《半小时漫画中国史》
  20. Cesium 源码解析 Model(一)

热门文章

  1. 火车站临时身份证明窗口位置。
  2. Friends 人物简介
  3. DateTime.Parse
  4. MySQL监控和预警
  5. 防止无协议脱欧 工党或支持英国推迟脱欧提案
  6. STM32 RT-Thread OS实战
  7. Python安全编程
  8. Word处理控件Aspose.Words功能演示:在 C# .NET 中将 DOC/DOCX 转换为 PNG
  9. 【前端 Canvas 训练营】第一期:鼠标交互粒子背景效果
  10. 少儿口才培训班有什么用?芒果叔叔刘老师给你分析