美文网首页
行为型模式之责任链模式

行为型模式之责任链模式

作者: BrotherTree | 来源:发表于2019-03-07 16:22 被阅读0次

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

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

在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
角色分析
  • Manager:抽象处理者角色,声明一个处理请求的方法,并保持对下一个处理节点Manager对象的引用
  • Boss:具体的处理者,对请求进行处理,如果不处理就讲请求转发给下一个节点上的处理对象(GeneralManager、OrdinaryManager同Boss)
优点
  • 降低耦合度,将请求的发送者和接收者解耦,便于拓展,提高代码灵活性。
  • 简化了对象。使得对象不需要知道链的结构。
  • 增强给对象指派责任节点的灵活性,通过改变链内的成员或者调动它们的次 序,允许动态地新增或者删除责任节点。
缺点
  • 如果责任链太长,或者每条链判断处理的时间太长会影响性能。特别是递归循环的时候。
  • 请求不一定能得到处理,可能会没有对象处理。

相关文章

网友评论

      本文标题:行为型模式之责任链模式

      本文链接:https://www.haomeiwen.com/subject/goycpqtx.html