责任链模式

责任链模式是将多个请求处理者连接起来,形成链状,不同的处理者对请求有不同的处理能力。当请求发送后,请求将沿着链状的处理者传递,直到被某个处理者处理。责任链模式避免了请求发送者与处理者的耦合关系,发送者不需要知道谁来处理请求,并且让所有的处理者都有机会处理请求。

Java中我们经常使用的用于捕获异常信息的try catch就是责任链模式的体现:

try {
            //需要捕获异常的代码
        } catch (Exception1 e1) {
            //处理第一种异常
        } catch (Exception2 e2) {
            //处理第二种异常
        } catch (Exception3 e3) {
            //处理第三种异常
        }//...

try块中的代码作为请求发送者,产生的异常信息就是请求,而每个catch块都可以看作是接收一个特殊类型参数的方法,即请求处理者。当异常被抛出时,异常处理机制将寻找与异常类型相匹配的第一个处理程序,然后执行catch中的代码,即请求被该处理者处理了。

Android中事件分发机制也是责任链模式的应用。手指触摸屏幕时,系统将对应的事件包装成一个事件对象,事件将自顶向下按照Activity->Window->顶级ViewGroup->子View的顺序传递。一旦某个View的dispatchTouchEvent方法返回true,就表示这个处理者拦截了这个事件,接着这个事件将会被这个处理者处理,它的onTouchEvent方法将会被调用。

同样Android中的广播也可以按照责任链模式来使用,BroadcastReceiver就是处理者。我们知道,广播分为普通广播和有序广播,普通广播发送后,所有注册了该广播的接收器都将收到消息。而有序广播是按照优先级来传播的,优先级高的广播接收器将先收到消息,然后可以决定是否将广播继续传递出去。通过对注册同一个有序广播的多个广播接收器设置不同的优先级,即可实现责任链模式处理广播事件。

责任链模式实现:简单的责任链模式

举例,我们在公司请假时,大公司一般都有完整的流程,根据不同的请假时间,审批人也有所不同。比如,临时请假一会儿出去一趟,直接跟组长请假就好了。请假1-3天,需要部门主管审批。3-10天以上则需要部长审批。这里的组长、主管、部长都是请求处理者,于是创建抽象处理者并实现:

/**
 * 抽象处理者
 */
public abstract class Handler {

    private final String TAG = this.getClass().getSimpleName();

    //下一个节点的处理者
    protected Handler nextHandler;

    /**
     * 处理请假的请求
     * @param day 请假天数
     */
    public void handleRequest(float day) {
        if (day < limit()) {
            System.out.println(TAG + " 审批 ");
        } else {
            nextHandler.handleRequest(day);
        }
    }

    /**
     * 能审批的天数
     * @return
     */
    public abstract float limit();
}
/**
 * 组长
 */
public class GroupLeader extends Handler {

    @Override
    public float limit() {
        return 1f;
    }
}
/**
 * 部长
 */
public class Minister extends Handler {

    @Override
    public float limit() {
        return 10f;
    }
}
/**
 * 主管
 */
public class Director extends Handler {

    @Override
    public float limit() {
        return 3f;
    }
}

使用时,要将处理者连接成链状,然后从第一个节点传入请求:

public static void main(String[] args) {
        Handler groupLeader = new GroupLeader();
        Handler director = new Director();
        Handler minister = new Minister();
        groupLeader.nextHandler = director;
        director.nextHandler = minister;

        groupLeader.handleRequest(5);
    }

以上的责任链中,发送的请求是固定的值,请求和处理者的规则是一定的。为了可以扩展更多的规则,我们可以将请求也抽象化,提供一个处理级别的方法。请求者需要判断自己的处理级别是否和请求级别相同:抽象的责任链模式

/**
 * 责任链模式——抽象处理者
 */
public abstract class AbstractHandler {

    //下一个节点的处理者
    public AbstractHandler nextHandler;

    /**
     * 处理请求
     * @param request
     */
    public final void handleRequest(AbstractRequest request) {
        if (request.getRequestLevel() == getHandleLevel()) {
            handle(request);
        } else {
            if (nextHandler != null) {
                nextHandler.handleRequest(request);
            } else {
                System.out.println("All handler can not handle this request");
            }
        }
    }

    /**
     * 获取处理级别
     * @return
     */
    public abstract int getHandleLevel();

    /**
     * 此处理者处理请求
     */
    protected abstract void handle(AbstractRequest request);
}
/**
 * 责任链模式——抽象请求者
 */
public abstract class AbstractRequest {

    //要处理的事件对象
    private String content;

    public AbstractRequest(String content) {
        this.content = content;
    }

    /**
     * 获取要处理的事件对象
     * @return
     */
    public String getContent() {
        return content;
    }

    /**
     * 获取请求级别
     * @return
     */
    public abstract int getRequestLevel();
}

实现多种请求和处理者,需要定义每个请求和处理者的级别:

/**
 * 具体处理者1
 */
public class Handler1 extends AbstractHandler {

    //此处理者的处理级别
    private static final int HANDLER_LEVEL = 1;

    @Override
    public int getHandleLevel() {
        return HANDLER_LEVEL;
    }

    @Override
    protected void handle(AbstractRequest request) {
        System.out.println("Handler" +
                HANDLER_LEVEL +
                " handle this request, level: " +
                request.getRequestLevel() +
                " content: " +
                request.getContent());
    }
}
/**
 * 具体处理者2
 */
public class Handler2 extends AbstractHandler {

    private static final int HANDLER_LEVEL = 2;

    @Override
    public int getHandleLevel() {
        return HANDLER_LEVEL;
    }

    @Override
    protected void handle(AbstractRequest request) {
        System.out.println("Handler" +
                HANDLER_LEVEL +
                " handle this request, level: " +
                request.getRequestLevel() +
                " content: " +
                request.getContent());
    }
}
/**
 * 具体处理者3
 */
public class Handler3 extends AbstractHandler {

    private static final int HANDLER_LEVEL = 3;

    @Override
    public int getHandleLevel() {
        return HANDLER_LEVEL;
    }

    @Override
    protected void handle(AbstractRequest request) {
        System.out.println("Handler" +
                HANDLER_LEVEL +
                " handle this request, level: " +
                request.getRequestLevel() +
                " content: " +
                request.getContent());
    }
}
/**
 * 具体请求者1
 */
public class Request1 extends AbstractRequest {

    //此请求者的请求级别
    private static final int REQUEST_LEVEL = 1;

    public Request1(String content) {
        super(content);
    }

    @Override
    public int getRequestLevel() {
        return REQUEST_LEVEL;
    }
}
/**
 * 具体请求者2
 */
public class Request2 extends AbstractRequest {

    private static final int REQUEST_LEVEL = 2;

    public Request2(String content) {
        super(content);
    }

    @Override
    public int getRequestLevel() {
        return REQUEST_LEVEL;
    }
}
/**
 * 具体请求者3
 */
public class Request3 extends AbstractRequest {

    private static final int REQUEST_LEVEL = 3;

    public Request3(String content) {
        super(content);
    }

    @Override
    public int getRequestLevel() {
        return REQUEST_LEVEL;
    }
}

使用方法相同:

public static void main(String[] args) {
        Handler1 handler1 = new Handler1();
        Handler2 handler2 = new Handler2();
        Handler3 handler3 = new Handler3();

        handler1.nextHandler = handler2;
        handler2.nextHandler = handler3;

        Request1 request1 = new Request1("content1");
        Request2 request2 = new Request2("content2");
        Request3 request3 = new Request3("content3");

        handler1.handleRequest(request1);
        handler1.handleRequest(request2);
        handler1.handleRequest(request3);
    }

抽象后的请求和处理者可以方便扩展更多的规则,而处理者只需要在属于自己级别范围的情况下处理请求即可。

总之,责任链模式可以让请求的发送者和处理者解偶,请求者只需要发出符合规则的请求,并明确请求的级别。单独的处理者除了要将自己无法处理的请求传给下一个处理者外,不需要关心其他处理者。责任链要求所有的处理者连接成链,可以方便地增加或删除处理者,当然,处理请求的过程需要遍历处理者,当处理者过多时,遍历可能会影响性能。

posted @ 2021-03-17 21:35  wanghan5950  阅读(95)  评论(0)    收藏  举报