责任链模式——使编程更有灵活性

(《设计模式解析与实战——何红辉,关爱民》读书笔记)

一、定义
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条线,并沿着这条链传递该请求,直到有对象处理它为止。
这类似于力的传递一样,一环套一环。
二、使用场景
(1)多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定;
(2)在请求处理者不明确的情况下向多个对象中的一个提交一个请求;
(3)需动态指定一组对象处理请求。
三、责任链模式的通用模式代码
简化版的通用模式代码:
Handler:抽象处理者角色,声明一个请求处理的方法,并在其中保持一个对下一个处理节点Handler对象的引用。
ConcreteHandler:具体处理者角色,对请求进行处理,如果不能处理则将该请求转发给下一个节点上的处理对象。


/**
 * 抽象处理者
 */
public abstract class Handler {
    /**
     *  下一节点处理者
     */
    protected Handler successor;

    /**
     * 请求处理
     * 
     * @param condition
     *            请求条件
     */
    public abstract void handlerRequest(String condition);
}
/**
 * 具体的处理者1
 */
public class ConcreteHandler1 extends Handler{

    @Override
    public void handlerRequest(String condition) {
        if (condition.equals("ConcreteHandler1")) {
            System.out.println("我是具体的处理者1");
            return;
        }else {
            successor.handlerRequest(condition);
        }
    }

}
/**
 * 具体的处理者2
 */
public class ConcreteHandler2 extends Handler{

    @Override
    public void handlerRequest(String condition) {
        if (condition.equals("ConcreteHandler2")) {
            System.out.println("我是具体的处理者2");
            return;
        }else {
            successor.handlerRequest(condition);
        }
    }

}
/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) {

        ConcreteHandler1 handler1 = new ConcreteHandler1();
        ConcreteHandler2 handler2 = new ConcreteHandler2();

        // 设置handler1的下一节点
        handler1.successor = handler2;
        // 设置handler2的下一节点
        handler2.successor = handler1;

        // 处理请求
        handler1.handlerRequest("ConcreteHandler2");
    }
}

运行结果:
这里写图片描述

上面的请求条件是一个字符串,然而在大多数情况下,责任链中的请求和对应的处理规则是不尽相同的,在这种情况下可以将请求进行封装,同时对请求的处理规则也进行封装作为一个独立的对象。

**
 * 抽象请求者
 */
public abstract class AbstractRequest {
    /**
     * 处理对象
     */
    private Object mObject;

    public AbstractRequest(Object object) {
        super();
        this.mObject = object;
    }

    /**
     * 获取处理的内容对象
     * 
     * @return 具体的内容对象
     */
    public Object getContent() {
        return mObject;
    }

    /**
     * 获取请求级别
     * 
     * @return 请求级别
     */
    public abstract int getRequestLevel();
}
/**
 * 抽象处理者
 */
public abstract class AbstractHandler {
    /**
     * 下一节点上的处理者对象
     */
    protected AbstractHandler nextHandler;

    /**
     * 处理请求
     * 
     * @param request
     *            请求对象
     */
    public final void handlerRequest(AbstractRequest request) {
        // 判断当前处理者对象的处理级别是否与请求者的处理级别一致
        if (getHanleLevel() == request.getRequestLevel()) {
            // 一致则由该处理对象处理
            handle(request);
        } else {
            // 否则将该请求对象转发给下一个节点上的请求对象
            if (nextHandler != null) {
                nextHandler.handlerRequest(request);
            } else {
                // 当所有处理者对象均不能处理该请求时输出
                System.out.println("All of handler can not handle the request!");
            }
        }
    }

    /**
     * 获取处理者对象的具体处理级别
     * 
     * @return 处理级别
     */
    protected abstract int getHanleLevel();

    /**
     * 获取处理者对象的具体处理方式
     * 
     * @param request
     *            请求者对象
     */
    protected abstract void handle(AbstractRequest request);
}
/**
 * 请求者1
 */
public class Request1 extends AbstractRequest{

    public Request1(Object object) {
        super(object);
    }

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

    public Request2(Object object) {
        super(object);
    }

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

    public Request3(Object object) {
        super(object);
    }

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

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

    @Override
    protected int getHanleLevel() {
        return 1;
    }

    @Override
    protected void handle(AbstractRequest request) {
        System.out.println("Handler1 handle request:" + request.getRequestLevel());
    }
}
/**
 * 处理者2
 */
public class Handler2 extends AbstractHandler {

    @Override
    protected int getHanleLevel() {
        return 2;
    }

    @Override
    protected void handle(AbstractRequest request) {
        System.out.println("Handler2 handle request:" + request.getRequestLevel());
    }
}
/**
 * 处理者3
 */
public class Handler3 extends AbstractHandler {

    @Override
    protected int getHanleLevel() {
        return 3;
    }

    @Override
    protected void handle(AbstractRequest request) {
        System.out.println("Handler3 handle request:" + request.getRequestLevel());
    }
}
/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        // 构造三个处理者对象
        AbstractHandler handler1 = new Handler1();
        AbstractHandler handler2 = new Handler2();
        AbstractHandler handler3 = new Handler3();

        // 设置当前处理者对象下一个节点的处理者对象
        handler1.nextHandler = handler2;
        handler2.nextHandler = handler3;

        // 构造三个请求者对象
        AbstractRequest request1 = new Request1("Request1");
        AbstractRequest request2 = new Request1("Request2");
        AbstractRequest request3 = new Request1("Request3");

        // 总是从链式的首端发起请求
        handler1.handlerRequest(request1);
        handler1.handlerRequest(request2);
        handler1.handlerRequest(request3);
    }
}

运行结果:
这里写图片描述
当然请求的发起可以从责任链的任何一个节点处开始,同时也可以改变责任链内部传递的规则。

四、优缺点
优点:
可以对请求者和处理者关系解耦,提高代码的灵活性。
缺点:
对请求处理者的遍历,如果处理者太多那么遍历必定会影响性能,特别是在一些递归调用中,要慎重。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值