前言
上文对工作流进行了一些基本的介绍,有了基础篇的内容,相信我们可以很容易抽象了一些实体模型:流程模型、开始节点模型、结束节点模型、任务节点模型、决策节点模型、分支节点模型、合并节点模型、边模型。
基础模型
我们把模型进行进一步抽象,可以得到基础模型,基础模型只包含两个属性,唯一编码和显示名称。
public class BaseModel {
private String name; // 唯一编码
private String displayName; // 显示名称
}
模型行为
如果按照面向对象来看,流程模型本身除了属性外,还应该具有方法和行为,即节点和边所能做的事,这里用Action接口来定义。
public interface Action {
public void execute(Execution execution);
}
因每个流程模型执行的条件可能不一样,这里统一使用Execution类来定义,下面先简单定义其必要属性,后续根据需要再追加。
public class Execution {
private String processInstanceId; // 流程实例ID
private String processTaskId; // 当前流程任务ID
// 执行对象扩展参数
private Dict args;
}
节点模型
流程模型由节点模型和边构成,节点的类型虽然很多,但是依然可以对其进行进一步抽象。节点都有自己通用性的行为,如前置拦截、后置拦截、日志处理等,除了通用性行为外,还可以根据子类不同的特性,实现exec抽象方法。
public abstract class NodeModel extends BaseModel implements Action {
private String layout;// 布局属性(x,y,w,h)
// 输入边集合
private List<TransitionModel> inputs = new ArrayList<TransitionModel>();
// 输出边集合
private List<TransitionModel> outputs = new ArrayList<TransitionModel>();
private String preInterceptors; // 节点前置拦截器
private String postInterceptors; // 节点后置拦截器
/**
* 由子类自定义执行方法
* @param execution
*/
@Override
abstract void exec(Execution execution);
@Override
public void execute(Execution execution) {
// 1. 调用前置拦截器
// 2. 调用子类的exec方法
// 3. 调用后置拦截器
exec(execution);
}
}
有了节点模型后,其他具体的节点模型就会显示相对简单。
开始节点模型
开始节点主要继承节点模型并实现其exec方法。
public class StartModel extends NodeModel {
@Override
public void exec(Execution execution) {
// 执行开始节点自定义执行逻辑
}
}
结束节点模型
结束节点也是继承节点模型并实现exec方法。
public class EndModel extends NodeModel {
@Override
public void exec(Execution execution) {
// 执行结束节点自定义执行逻辑
}
}
任务节点模型
任务节点是流程中非常重要的节点,其拥有更多自己的属性。当然,下面只是把常用的属性罗列出来,后续也根据具体实现的业务,增加和删除其属性。
public class TaskModel extends NodeModel {
private String form; // 表单标识
private String assignee; // 参与人
private String assignmentHandler; // 参与人处理类
private TaskTypeEnum taskType; // 任务类型(主办/协办)
private TaskPerformTypeEnum performType; // 参与类型(普通参与/会签参与)
private String reminderTime; // 提醒时间
private String reminderRepeat; // 重复提醒间隔
private String expireTime; // 期待任务完成时间变量key
private String autoExecute; // 到期是否自动执行Y/N
private String callback; // 自动执行回调类
private Dict ext = Dict.create(); // 自定义扩展属性
@Override
public void exec(Execution execution) {
// 执行任务节点自定义执行逻辑
}
}
决策节点模型
决策节点也是一种特殊节点,其会有决策表达式,和决策处理类属性,主要用于动态计算下一个节点的走向。
public class DecisionModel extends NodeModel {
private String expr; // 决策表达式
private String handleClass; // 决策处理类
@Override
public void exec(Execution execution) {
// 执行决策节点自定义执行逻辑
}
}
分支节点模型
当用到并行流程的时候,该节点就派上用场了,这里只是先简单定义,后续也会根据具体的业务需要,扩展新的属性。
public class ForkModel extends NodeModel {
@Override
public void exec(Execution execution) {
// 执行分支节点自定义执行逻辑
}
}
合并节点模型
合并节点和分支节点是一起出来的,这里也是先按照最基础的定义。
public class JoinModel extends NodeModel {
@Override
public void exec(Execution execution) {
// 执行合并节点自定义执行逻辑
}
}
边模型
两节点连线,就构成一条边,所以边的关系属性就是source和target,边也有自己的执行方法。
public class TransitionModel extends BaseModel implements Action {
private NodeModel source; // 边源节点引用
private NodeModel target; // 边目标节点引用
private String to; // 目标节点名称
private String expr; // 边表达式
private String g; // 边点坐标集合(x1,y1;x2,y2,x3,y3……)开始、拐角、结束
private boolean enabled; // 是否可执行
@Override
public void execute(Execution execution) {
}
}
流程模型
有了上面的元素,那么流程模型就很容易得到如下定义:
public class ProcessModel extends BaseModel {
private String type; // 流程定义分类
private String instanceUrl; // 启动实例要填写的表单key
private String expireTime; // 期待完成时间变量key
private String instanceNoClass; // 实例编号生成器实现类
// 流程定义的所有节点
private List<NodeModel> nodes = new ArrayList<NodeModel>();
// 流程定义的所有任务节点
private List<TaskModel> tasks = new ArrayList<TaskModel>();
}
来个简单的模型对象
public class BuildProcessTest {
@Test
public void buildProcessModel() {
ProcessModel processModel = new ProcessModel();
StartModel startModel = new StartModel();
startModel.setName("start");
startModel.setDisplayName("开始");
processModel.getNodes().add(startModel);
TransitionModel t1 = new TransitionModel();
t1.setName("t1");
t1.setTo("apply");
t1.setSource(startModel);
startModel.getOutputs().add(t1);
TaskModel applyTaskModel = new TaskModel();
t1.setTarget(applyTaskModel);
applyTaskModel.setName("apply");
applyTaskModel.setDisplayName("请假申请");
processModel.getNodes().add(applyTaskModel);
processModel.getTasks().add(applyTaskModel);
TransitionModel t2 = new TransitionModel();
t2.setName("t2");
t2.setTo("deptApprove");
t2.setSource(applyTaskModel);
applyTaskModel.getOutputs().add(t2);
TaskModel deptApproveTaskModel = new TaskModel();
t2.setTarget(deptApproveTaskModel);
deptApproveTaskModel.setName("deptApprove");
deptApproveTaskModel.setDisplayName("部门领导审批");
processModel.getNodes().add(deptApproveTaskModel);
processModel.getTasks().add(deptApproveTaskModel);
TransitionModel t3 = new TransitionModel();
t3.setName("t3");
t3.setTo("end");
t3.setSource(deptApproveTaskModel);
deptApproveTaskModel.getOutputs().add(t3);
EndModel endModel = new EndModel();
t3.setTarget(endModel);
endModel.setName("end");
endModel.setDisplayName("结束");
processModel.getNodes().add(endModel);
}
}
加入组织
请在微信中打开:
《立东和他的朋友们》