设计模式之责任链模式

22 篇文章 0 订阅
17 篇文章 0 订阅

定义

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

通用类图

责任链模式类图

具体实现

责任链模式的目的是为了让发送者和接收者解耦,发送者不需要知道请求是由哪个接收者处理,只需要把请求给到由多个对象组成的处理链的头节点,抽象处理类 Handler 会判断是否是本节点要处理的请求,是的话处理请求,不是的话把请求传递给下一个处理者。

抽象处理者:Handler

package com.yrs.chainOfResponsibility;

/**
 * @Author: yangrusheng
 * @Description: 抽象处理者。主要作用请求接收、传递。
 * @Date: Created in 17:04 2020/1/11
 * @Modified By:
 */
public abstract class Handler {

    /**
     * 下一个责任链节点
     */
    private Handler nextHandler;

    public final void handleRequest(Request request) {
        if (request.getLevel() == this.getLevel()) {
            //此节点处理
            this.doHandle(request);
        } else {
            //判断是否有下个处理节点,传递请求
            if (nextHandler != null) {
                this.nextHandler.handleRequest(request);
            } else {
                System.out.println("this request not handler handle!");
            }
        }
    }

    /**
     * 设置下个处理节点
     * @param nextHandler
     */
    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    /**
     * 获得处理者能够处理的请求的等级
     * @return
     */
    protected abstract int getLevel();

    /**
     * 处理请求
     */
    protected abstract void doHandle(Request request);
}

具体处理者:ConcreteHandler

package com.yrs.chainOfResponsibility;

/**
 * @Author: yangrusheng
 * @Description: 具体处理者
 * @Date: Created in 17:26 2020/1/11
 * @Modified By:
 */
public class ConcreteHandler1 extends Handler {
    @Override
    protected int getLevel() {
        return 1;
    }

    @Override
    protected void doHandle(Request request) {
        System.out.println("concreteHandler1 handle request: " + request.getMsg());
    }
}
package com.yrs.chainOfResponsibility;

/**
 * @Author: yangrusheng
 * @Description: 具体处理者
 * @Date: Created in 17:26 2020/1/11
 * @Modified By:
 */
public class ConcreteHandler2 extends Handler {
    @Override
    protected int getLevel() {
        return 2;
    }

    @Override
    protected void doHandle(Request request) {
        System.out.println("concreteHandler2 handle request: " + request.getMsg());
    }
}

请求类:Request

package com.yrs.chainOfResponsibility;

/**
 * @Author: yangrusheng
 * @Description: 请求类
 * @Date: Created in 17:07 2020/1/11
 * @Modified By:
 */
public class Request {

    /**
     * 处理级别
     */
    private int level;

    /**
     * 处理内容
     */
    private String msg;

    public Request() {

    }

    public Request(int level, String msg) {
        this.level = level;
        this.msg = msg;
    }

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

场景类:Client

package com.yrs.chainOfResponsibility;

/**
 * @Author: yangrusheng
 * @Description:
 * @Date: Created in 17:04 2020/1/11
 * @Modified By:
 */
public class Client {

    public static void main(String[] args) {
        Request request1 = new Request(1, "request1");
        Request request2 = new Request(2, "request2");
        Handler handler1 = new ConcreteHandler1();
        Handler handler2 = new ConcreteHandler2();
        //设置下一个处理节点
        handler1.setNextHandler(handler2);
        //提交请求
        handler1.handleRequest(request1);
        handler1.handleRequest(request2);
    }

}

优缺点

责任链模式的优点:

  • 将请求的发送者和接受者解耦。
  • 可以简化对象,因为它不需要知道链的结构。
  • 通过改变链内的成员或调动他们的次序,允许动态地新增或者删除责任。

责任链模式的缺点:

  • 性能问题。每个请求都要从链头开始遍历,在链比较长的时候,性能将会是一个问题。
  • 调试不方便,不容易定位问题。

使用场景

父类实现了请求传递的功能,子类实现请求的处理,符合单一职责原则。请求到底是谁处理的,请求者不用关心,只需把请求抛给责任链的第一个处理着,最终会返回一个处理结果(也可以不处理),这是责任链模式的核心。

当不同类型的事件,需要不同的处理方式就可以使用责任链模式,但是要注意控制链中节点数量,避免出现超长链的情况,这样会影响程序性能

参考

  • 《设计模式之禅-第2版》
  • 《Head First 设计模式》
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值