概述

责任链模式是对象的行为模式。使多个对象都有机会处理请求,从而避免请求的发送者和接受者直接的耦合关系。将这些对象连成一条链,沿着这条链传递该请求,直到有一个对象处理它为止。

依照惯例,先贴上维基百科的定义:

In object-oriented design, the chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects.[1] Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.

在面向对象的设计中,责任链模式由命令对象源和一系列处理对象组成。每个处理对象包含了一定的处理逻辑,剩下的就是把它传递到责任链中的下一个对象。

UML 图

可以看到这个图,由一个 Client 类 和一个 Handler 抽象类 还有具体实现类组成。

其中 Client类包含了一个抽象处理对象的引用,用于和客户进行交互,它将处理逻辑交给 Handler类,每一个具体的 Handler类中还有一个 handlerRequest()函数用于把剩下的任务交给下一个处理对象。

下面利用责任链模式,模拟了一个小码农请假的过程。

package com.ans;

abstract class Handler {
    private Handler successor;
    public abstract void handleRequest(int days);
    public void setSuccessor(Handler handler) {
        this.successor = handler;
    }

    public Handler getSuccessor() {
        return successor;
    }
}


class GroupLeader extends Handler {
    @Override
    public void handleRequest(int days) {
        if(days <= 3) {
            System.out.println("组长批示,准了");
        } else {
            System.out.println("申请时间太长,组长做不了主,交由总监处理");
            getSuccessor().handleRequest(days);
        }

    }

}

class Inspector extends Handler {
    @Override
    public void handleRequest(int days) {
        if(days <= 7) {
            System.out.println("总监批示,准了");
        } else {
            System.out.println("申请时间太长,总监做不了主,交由经理处理");
            getSuccessor().handleRequest(days);
        }

    }
}

class CEO extends Handler {
    @Override
    public void handleRequest(int days) {
        if(days <= 15) {
            System.out.println("经理批示,准了");
        } else {
            System.out.println("申请时间太长,不准假");
            getSuccessor().handleRequest(days);
        }    
    }
}


public class ResponsibilityChain {
    public static void main(String[] args) {
        //create the nodes
        GroupLeader leader = new GroupLeader();
        Inspector ins = new Inspector();
        CEO ceo = new CEO();

        //build the responsibility chain
        leader.setSuccessor(ins);
        ins.setSuccessor(ceo);

        //begin to execute
        leader.handleRequest(16);
        System.out.println("==============================");
        leader.handleRequest(8);
    }
}

运行结果:

申请时间太长,组长做不了主,交由总监处理
申请时间太长,总监做不了主,交由经理处理
申请时间太长,不准假
==============================
申请时间太长,组长做不了主,交由总监处理
申请时间太长,总监做不了主,交由经理处理
经理批示,准了

每一个人的准假能力都在一定的范围之内,如果超出自己的范围则移交上一级批准。

总结

责任链模式的优点是调用者不需知道具体谁来处理请求,也不知道链的具体结构,降低了节点域节点的耦合度;可在运行时动态修改链中的对象职责,增强了给对象指派职责的灵活性;

缺点是没有明确的接收者,可能传到链的最后,也没得到正确的处理。

学习设计模式画图很重要,只有思路清晰了,才能写准确。