流程引擎学习轨迹

流程引擎学习轨迹

我为什么要学流程引擎?源头就在于,领导让我了解一下公司某项目组开发的流程引擎的使用然后集成到我们现有项目中,我兴致冲冲地各种搜集资料,结果只是初步了解便满脸问号。虽然表面看上去完成了,功能可使用,但是该有的文档也没有,就一个简单的入门视频,视频里面的页面还和实际功能有出入,此外功能页面上很多小图标却连个解释也没有,想自学也无从下手。听其他使用过的同事说,该项目组进行组织架构调整,有bug一个月都没解决了。这可咋办,无法交差了…

不过转念一想,其实流程引擎已经有成熟的方案,我要是流程引擎项目组的人,开发初期一定会对市面上已有的项目进行调研,别人的交互方式、实现方式都会成为参考,甚至日后灵感的来源。所以与其费劲脑汁研究公司不成熟的项目,倒不如先学学市面上已有的方案,抓住主要矛盾,再学任何的流程引擎都可举一反三。

关于流程引擎我的学习轨迹如下:
1. 学习公司流程引擎:失败;
2. 了解到流程引擎已有成熟方案:flowable为成熟框架。但是到底什么是流程引擎?
3. 学习流程引擎概念:发现很多文章将其与状态机做对比,状态机是一个比较基础的概念。
4. 学习一下状态机。

所以我先了解一下状态机的实现:

状态机的概念

状态机主要是处理状态变更的情况,简单来说包含一下要素:
– state 当前状态
– event 触发事件
– transition 状态变换,下一个状态
– action 要执行的动作

状态机的几种实现方式

1.switch…case
public class StateMachine{

    public State currentState;

    public void transition(Event event){
        if(currentState == xxx状态){
                switch(event){
                    case 事件1:
                        action();
                        nextState=xxx;
                    case 事件2:
                        //...
                }
        }
    }
}

举一个实际例子

class Document {
    field state: string
    // ...
    method publish() {
        switch (state)
            "draft":
                state = "moderation"
                break
            "moderation":
                if (currentUser.role == "admin")
                    state = "published"
                break
            "published":
                // 什么也不做。
                break
    // ...
    }
}

该方法实现简单,思维方式比较直接,状态及事件较少的时候实现简单。但是后期在复杂情况下,需要维护以及嵌套大量判断语句,不够优雅,扩展性较差。

2.基于设计模式——状态模式

设计思路在于:一个实体对象基于其不同状态会有不同的行为模式,因此状态模式将关注点集中在行为,即实体类中抽象行为方法且保存一个当前状态的引用。因此,将状态抽象为类,不同状态不同的行为由状态本身维护,实体上下文本身不关心。
适用于:行为随着状态不同而发生改变的场景,作为条件分支的替代。在行为受状态约束的时候使用状态模式,而且状态不超过 5 个。

举一个实际例子,由于拥有浅薄的电商经验,所以对于用户订单退款这件事耿耿于怀。而退款中的状态扭转在这里可以作为一个很好的事例来说明:

/**
    1.用户申请退款:订单若已付款但是未发货,无需商家处理直接退款成功
    2.用户申请退款:订单若已经发货,需要商家处理,商家同意直接退款成功,商家不同意退款失败
    3.用户申请退款:订单若已签收,用户申请退款失败,需要进入退货流程

    状态:订单已付款未发货、订单已发货、订单已签收、订单退款成功、订单退款失败、订单退货中
    触发事件:用户要退款
    不同状态的通用行为:处理退款情况
**/

public static void main(){
        Order order=new Order();
        order.changeState(new NoSendState());//设置当前订单状态是 已付款未发货状态
        order.needRefund();//申请退款
}

//订单
public class Order {
    public State currentState;


    public void changeState(State newState) {
        this.currentState = newState;
    }

    //申请退款
    public void needRefund() {
        sendMsgToUser();
        currentState.processOfRefund(this);
    }

    public void sendMsgToUser() {
        System.out.println("当前状态为:" + currentState.getStateName());
    }
}
//状态
public abstract class State{

    public abstract String getStateName();
    public abstract void processOfRefund(Order order); //退款处理
}
//未发货状态
public class NoSendState extends State {

    @Override
    public String getStateName() {
        return "已付款未发货状态";
    }

    public void processOfRefund(Order order){
        order.changeState(new RefundSuccess());//修改状态
        order.needRefund();
        //该方法可以继续解耦订单与状态处理的关心,维护一个中间消息,使状态处理不关心订单的方法
    }
}


//退款成功状态
public class RefundSuccess extends State {


    @Override
    public String getStateName() {
        return "退款成功";
    }

    public void processOfRefund(Order order){
        System.out.println("退款成功,订单关闭");

    }
}

运行结果为:

当前状态为:已付款未发货状态
当前状态为:退款成功
退款成功,订单关闭

状态模式将每一个状态抽象为对象,以状态为切入点处理订单,不同的状态有不同的行为。该做法优点在于对订单屏蔽不同状态的具体处理,订单只需要关心订单本身的”退款“行为,维护当前状态即可,至于在不同状态如何处理”退款”请求,订单不关心。这种做法更有利于上层调用方对于订单数据的维护,编写代码时可以比较方便的增加新的状态,并且只需要改变对象的状态就可以改变对象的行为。
但是由于要为每一个状态创建类,在状态过多的情况下,会导致内存资源的浪费,开发繁琐。

《未完》

发表评论

电子邮件地址不会被公开。