7、状态模式(State Pattern)

2020-08-03  本文已影响0人  火山_6c7b

1. 状态模式

1.1 简介

  State Pattern是属于行为模式,类的行为是基于它的状态改变的。在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。

  当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。

特点:

1.2 结构

UML结构图如下:


State Pattern uml.png

模式中的角色:

2. 实现

2.1 示例

  我们以审批流为例,如果发起一个请假流程,第一节点就是部门领导审核,部门领导审核通过会继续往下走,进入下一个节点,人力资源部门审核,当然人力资源也可以驳回请求,人力资源审核通过之后就可以休假了。

审批节点虚拟类:

public abstract class Node {
    private static String name;

    public abstract void nodeHandle(FlowContext context);
    protected abstract boolean isPermission(String message);

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

上下文环境类:

public class FlowContext {

    // 流程状态 0:通过 1:退回整改-添加时间 2.退回整改-添加部门 3.已申请 4.结束
    private int status;
    private String message;
    private Node node;

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Node getNode() {
        return node;
    }

    public void setNode(Node node) {
        this.node = node;
    }
}

部门直属领导审批节点类:

public class LeadNode extends Node {

    @Override
    public void nodeHandle(FlowContext context) {
        if (context == null || 4 == context.getStatus()) {
            System.out.println("无审核内容或流程已经结束");
            return;
        }
        if (3 != context.getStatus()) { // 审核节点校验
            System.out.println("无审核内容或非当前节点审批");
            return;
        }

        if (!isPermission(context.getMessage())) {
            System.out.println("审批未通过,请加上请假时间");
            context.setStatus(1);
            context.setNode(new WorkerNode());
            context.setStatus(2);
            context.getNode().nodeHandle(context);
            return;
        }

        System.out.println(context.getMessage());
        setName("张经理");
        context.setMessage(context.getMessage() + getName() + "审核通过;");
        context.setStatus(0);
        context.setNode(new HrNode());
        // 调用下个审批节点审批动作,继续审批流
        context.getNode().nodeHandle(context);
    }

    @Override
    protected boolean isPermission(String message){
        if (StringUtils.isBlank(message)){
            return false;
        }
        if (!message.contains("时间:")){
            return false;
        }
        return true;
    }
}

hr审核节点类:

public class HrNode extends Node {

    @Override
    public void nodeHandle(FlowContext context) {
        if (context == null || 4 == context.getStatus()) {
            System.out.println("无审核内容或流程已经结束");
            return;
        }
        if (0 != context.getStatus()) { // 审核节点校验
            System.out.println("上一节点审批未通过");
            return;
        }
        if (!isPermission(context.getMessage())) {
            System.out.println("审批未通过,请补充部门信息");
            context.setStatus(2);
            context.setNode(new WorkerNode());
            context.getNode().nodeHandle(context);
            return;
        }

        setName("HR李");
        System.out.println(context.getMessage() + getName() + "审核通过");
        // 审核终结不再流转
        context.setStatus(4);
        context.setEnd(true);
    }

    @Override
    protected boolean isPermission(String message){
        if (StringUtils.isBlank(message)){
            return false;
        }
        if (!message.contains("部门:")){
            return false;
        }
        return true;
    }
}

员工类:

public class WorkerNode extends Node {

    @Override
    public void nodeHandle(FlowContext context) {
        if (context == null || 4 == context.getStatus()) {
            System.out.println("无审核内容或流程已经结束");
            return;
        }
        if (1 == context.getStatus()) {
            System.out.println("添加时间");
            context.setMessage(context.getMessage()+",时间:两天!");
            context.setNode(new LeadNode());
            context.setStatus(3);
            context.getNode().nodeHandle(context);
            return;
        }
        if (2 == context.getStatus()) {
            System.out.println("添加部门");
            context.setMessage(context.getMessage()+",部门:市场部!");
            context.setNode(new LeadNode());
            context.setStatus(3);
            context.getNode().nodeHandle(context);
            return;
        }
    }

    public void start() {
        FlowContext context = new FlowContext();
        context.setMessage("请假三天,望审核通过");
        Node node = new LeadNode();
        context.setNode(node);
        context.setStatus(3);
        context.getNode().nodeHandle(context); // 发起请求

        if (4 == context.getStatus()) {
            System.out.println("审核通过,开始休假!");
            return;
        }
        System.out.println("审核未通过,放弃休假或重新申请!");
    }

    @Override
    protected boolean isPermission(String message){
    }
}

客户端调用示例类:

    public static void main(String[] args) {
        WorkerNode node = new WorkerNode();       
        node.start();        
    }

2.2 总结

状态模式优点:

状态模式缺点:

上一篇 下一篇

猜你喜欢

热点阅读