为什么要用设计模式系列之职责链模式

在生活中经常见到这样的流程:员工请假,先由项目组长审批,再由部门经理审批,最后由人事归档。

每个审批环节都对应着不同的角色,每个角色有不同的职责,处理完职责对应的工作后,再将任务传递给下一个。

其实,在我们程序开发中,这种职责链也常常出现。笔者在这里以HTTP请求举个例子。

我们知道HTTP是基于TCP的应用层协议,当用户从浏览器发起一个请求时,服务器接收到的实际是二进制数据,服务器会将二进制数据按照HTTP协议规范进行解码,从而得到HTTP原始对象,而我们往往需要把HTTP原始对象中再转成我们的Java对象或者JsonObject。这样想想,这个解码动作是不是层层传递的。有将二进制数据转成HTTP对象的解码器,然后又传递给将HTTP对象转成我们业务需要的Java对象的解码器,最后再将解码后的对象传递给实际业务处理器(Handler/Controller)。

上面举的这个例子在Netty中就得到了很好的体现。对Netty有接触过的同学应该知道pipeline。pipeline就是职责链模式的实现。

说了这么多,不如来点实际的,笔者用Java实现一个员工请假审批的职责链。需求如下:

当请假天数 days <= 5 先由项目组长审批后,再传递给部门经理审批,最后再由部门经理传递给人事归档。当请假天数 days > 5 的时候项目组长和部门经理都会拒绝审批,不再传递。

1、编写假条类 Leave.java

package com.javafm.chain;

public class Leave {
    private String name;
    private int days;

    public String getName() {
        return name;
    }

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

    public int getDays() {
        return days;
    }

    public void setDays(int days) {
        this.days = days;
    }
}

2、编写审批的抽象类 Approval.java

package com.javafm.chain;

public abstract class Approval {
    // 审批者名称
    private String name;
    // 下一个审批者
    protected Approval next;

    public Approval(String name) {
        this.name = name;
    }

    public void addLast(Approval approval) {
        this.next = approval;
    }

    public String getName() {
        return name;
    }

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

    public void process(Leave leave) {
        System.out.println(this.getName() + "处理了审批:" + leave.getName() + " 请假 " + leave.getDays() + " 天");
    }
}

3、编写项目组长审批类 Leader.java

package com.javafm.chain;

public class Leader extends Approval {
    public Leader() {
        super("项目组长");
    }

    @Override
    public void process(Leave leave) {
        super.process(leave);
        if (leave.getDays() > 5) {
            System.out.println(this.getName() + "拒绝了该申请");
        } else {
            this.next.process(leave);
        }
    }
}

4、编写部门经理审批类 Manager.java

package com.javafm.chain;

public class Manager extends Approval {

    public Manager() {
        super("部门经理");
    }

    @Override
    public void process(Leave leave) {
        super.process(leave);
        if (leave.getDays() > 5) {
            System.out.println(this.getName() + "拒绝了该申请");
        } else {
            this.next.process(leave);
        }
    }
}

5、编写人事归档类

package com.javafm.chain;

public class HrMM extends Approval {

    public HrMM() {
        super("HR MM");
    }

    @Override
    public void process(Leave leave) {
        System.out.println(this.getName() + "归档完毕:" + leave.getName() + " 请假 " + leave.getDays() + " 天");
    }
}

从上面的代码可以看到项目组长审批类、项目经理审批类、人事归档类都继承了审批的抽象类。并且重写了process方法。

5、编写测试代码 Main.java

package com.javafm.chain;

public class Main {
    public static void main(String[] args) {
        Leave leave = new Leave();
        leave.setName("皮花猫");
        leave.setDays(3);

        Approval leader = new Leader();
        Approval manager = new Manager();
        Approval hrmm = new HrMM();

        leader.addLast(manager);
        manager.addLast(hrmm);

        leader.process(leave);
    }
}

6、运行测试代码后,在控制台会输出以下信息,从中可以看到审批流程是按职责层层传递的。

本博客采用 知识共享署名-禁止演绎 4.0 国际许可协议 进行许可

本文标题:为什么要用设计模式系列之职责链模式

本文地址:https://jizhong.plus/post/2020/04/chain.html