行为型模式之责任链模式

2019-03-07  本文已影响0人  BrotherTree

在设计模式中,责任链模式是属于行为模式,请求从一个起点开始,沿着任务链依次传递给下一个节点,直到某个节点处理了该请求而结束。

责任链中的每个节点都有机会去处理该请求,且发送方不需要关心接收方(链)的结构,这样就有效的避免了发送者和接收者之间的耦合。

在Android中,Touch事件分发流程就是典型的责任链模式,事件沿着Activity、ViewGroup和View传递,直到其中某一方消费了该事件为止。


image.png
举个栗子

公司员工级别:普通员工、部门经理、总经理、老板
普通员工需要请假,2天需要部门经理批准,5天需要总经理批准,10天需要老板批准。

首先,编写员工类

public class Staff {

    // 员工需要请假天数所在level
    // 1:10天以内,此时需Boss批准
    // 2:5天以内,此时需GeneralManager批准
    // 3:2天以内,此时需OrdinaryManager批准
    // 其他:谁也不会批准
    private int level;

    // 请假描述
    private String request;

    public Staff(int level) {
        this.level = level;
        switch (this.level) {
            case 1:
                this.request = "员工请假10天以内";
                break;
            case 2:
                this.request = "员工请假5天以内";
                break;
            case 3:
                this.request = "员工请假2天以内";
                break;
            default:
                this.request = "员工请假超过10天";
                break;
        }
    }

    // 获取员工需要请假天数所在level
    public int getLevel() {
        return level;
    }

    // 请假描述
    public String getRequest() {
        return request;
    }
}

编写Manger类,此类是一个抽象类

public abstract class Manager {

    // 员工等级
    public static final int BOSS = 1;// 老板
    public static final int GENERAL_MANAGER = 2;// 总经理
    public static final int ORDINARY_MANAGER = 3;// 部门经理

    private int level;

    private Manager nextManger;

    public Manager(int level) {
        this.level = level;
    }

    // 设置下一个处理节点
    public void setNextManger(Manager nextManger) {
        this.nextManger = nextManger;
    }

    public final void request(Staff staff) {
        // 获取请假等级和当前manager等级进行比较,如果相等,则当前manager有权限批准
        if (staff.getLevel() == level) {
            // 调用子类manager的处理
            response(staff);
        } else {
            // 如果nextManger不为null,即存在下一个处理节点
            if (nextManger != null) {
                // 下一个处理节点来处理该请求,这里使用了递归调用
                nextManger.request(staff);
            } else {
                // 没有下一个处理者
                System.out.println("项目紧张,无法批准这么多天假期");
                System.out.println("==========================");
            }
        }
    }

    // 抽象方法,需要子类实现
    protected abstract void response(Staff staff);
}

下面是实现三个Manger的子类

// 老板
public class Boss extends Manager {

    public Boss() {
        super(Manager.BOSS);
    }

    // 处理请求
    @Override
    protected void response(Staff staff) {
        System.out.println("员工问Boss");
        System.out.println(staff.getRequest());
        System.out.println("Boss回答OK");
        System.out.println("==========================");
    }
}
// 总经理
public class GeneralManager extends Manager {

    public GeneralManager() {
        super(Manager.GENERAL_MANAGER);
    }

    // 处理请求
    @Override
    protected void response(Staff staff) {
        System.out.println("员工问GeneralManager");
        System.out.println(staff.getRequest());
        System.out.println("GeneralManager回答OK");
        System.out.println("==========================");
    }
}
// 部门经理
public class OrdinaryManager extends Manager {

    public OrdinaryManager() {
        super(Manager.ORDINARY_MANAGER);
    }

    // 处理请求
    @Override
    protected void response(Staff staff) {
        System.out.println("员工问OrdinaryManager");
        System.out.println(staff.getRequest());
        System.out.println("OrdinaryManager回答OK");
        System.out.println("==========================");
    }
}

最后是发起员工的请假事宜

public class TestMain {

    public static void main(String[] args) {

        // 1...4之间随机数,作为员工请假等级,对应manager的等级
        Random random = new Random();
        ArrayList<Staff> arrayList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            arrayList.add(new Staff(random.nextInt(4)));
        }

        // 三个manager对象
        Manager ordinaryManager = new OrdinaryManager();
        Manager generalManager = new GeneralManager();
        Manager boss = new Boss();

        // 设置责任链的下一个处理节点
        // 部门经理之后是总经理
        ordinaryManager.setNextManger(generalManager);
        // 总经理之后是老板
        generalManager.setNextManger(boss);

        // 为了体现不同请假等级后的不同处理情况,这里用一个数组来产生多个请求
        for (Staff staff : arrayList) {
            // 开始第一个节点的请求
            ordinaryManager.request(staff);
        }
    }
}

执行结果(随机)

员工问OrdinaryManager
员工请假2天以内
OrdinaryManager回答OK
==========================
员工问OrdinaryManager
员工请假2天以内
OrdinaryManager回答OK
==========================
员工问OrdinaryManager
员工请假2天以内
OrdinaryManager回答OK
==========================
员工问GeneralManager
员工请假5天以内
GeneralManager回答OK
==========================
员工问OrdinaryManager
员工请假2天以内
OrdinaryManager回答OK
==========================
员工问OrdinaryManager
员工请假2天以内
OrdinaryManager回答OK
==========================
员工问OrdinaryManager
员工请假2天以内
OrdinaryManager回答OK
==========================
项目紧张,无法批准这么多天假期
==========================
员工问GeneralManager
员工请假5天以内
GeneralManager回答OK
==========================
项目紧张,无法批准这么多天假期
==========================

Process finished with exit code 0
image.png
角色分析
优点
缺点
上一篇下一篇

猜你喜欢

热点阅读