努力保头发的打工人
努力保头发的打工人
发布于 2021-01-24 / 27 阅读 / 0 评论 / 0 点赞

责任链模式

1 概述

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

责任链模式的重点是链,用一条链处理相似的请求,并返回结果,通用类图如下:

责任链模式类图.png

2 优缺点

2.1 优点

将请求和处理分开,请求者可以不知道是谁处理的,处理者可以不知道请求的全貌,两者解耦,提高了系统的灵活性。

2.2 缺点
  • 性能差 每个请求都需要从头到尾走一遍。

  • 调试困难 链条比较长的时候,debug会比较复杂。

3 代码示例

代码核心就一个责任链处理者的抽象类,我们这里结合一下模板方法模式,因为每个处理者的逻辑是相似的,处理逻辑是相同的,如:判断是不是自己负责的,传递到下一个处理者,具体处理。每个类具体处理方法不同而已,正好适合加入模板方法模式。

创建一个请求消息类:

/**
 * @author chiangtaol
 * @date 2020-12-04
 * @describe 请求信息
 */
@Data
@Builder
public class RequestMessage {
​
    /**
     * 请求级别,复杂业务可以使用自定义对象
     */
    private Integer level;
​
    /**
     * 请求的事情
     */
    private String msg;
}

整个责任链模式重点是下面这个处理者抽象类,首先定义每个处理类都要有表明自己链的后面是那个处理者的方法,然后使用模板方法模式,定义好处理请求的过程,每个处理者不同的地方,如自己的处理级别,具体如何处理等写好抽象方法,让具体的处理者实现。

/**
 * @author chiangtaol
 * @date 2020-12-04
 * @describe 请求处理抽象类
 */
public abstract class HandlerAbstract {
​
    // 责任链的下一个
    private HandlerAbstract nextHandler;
​
    public void setNext(HandlerAbstract nextHandler) {
        this.nextHandler = nextHandler;
    }
​
    // 处理请求
    public final String handleRequest(RequestMessage requestMessage){
        String result;
        // 如果级别对应就处理,否则交给后面的处理
        if (this.getHandlerLevel() == requestMessage.getLevel()){
            result = this.handlerDo(requestMessage);
        }else {
            if (this.nextHandler != null){
                result = this.nextHandler.handleRequest(requestMessage);
            }else {
                System.out.println("没有对应级别处理方式,快看看代码哪里写错了!!");
                result = "";
            }
        }
        return result;
    }
​
​
    /** 获取处理的级别*/
    protected abstract int getHandlerLevel();
​
    /** 具体执行方法*/
    protected abstract String handlerDo(RequestMessage requestMessage);
}

下面就写一些具体处理者代码:

/**
 * @author chiangtaol
 * @date 2020-12-04
 * @describe 责任处理者1
 */
public class Handler1 extends HandlerAbstract {
    /**
     * 获取处理的级别
     */
    @Override
    protected int getHandlerLevel() {
        return 1;
    }
​
    /**
     * 具体执行方法
     */
    @Override
    protected String handlerDo(RequestMessage requestMessage) {
        return "处理者1处理了请求..."+requestMessage.getMsg();
    }
}
​
/**
 * @author chiangtaol
 * @date 2020-12-04
 * @describe 责任处理者2
 */
public class Handler2 extends HandlerAbstract {
    /**
     * 获取处理的级别
     */
    @Override
    protected int getHandlerLevel() {
        return 2;
    }
​
    /**
     * 具体执行方法
     */
    @Override
    protected String handlerDo(RequestMessage requestMessage) {
        return "处理者2处理了请求..."+requestMessage.getMsg();
    }
}
/**
 * @author chiangtaol
 * @date 2020-12-04
 * @describe 责任处理者3
 */
public class Handler3 extends HandlerAbstract{
    /**
     * 获取处理的级别
     */
    @Override
    protected int getHandlerLevel() {
        return 3;
    }
​
    /**
     * 具体执行方法
     */
    @Override
    protected String handlerDo(RequestMessage requestMessage) {
        return "处理者3处理了请求..."+requestMessage.getMsg();
    }
}

最后可以定义一个责任链的管理者,稍微封装下所有链上顺序的定义,并返回链上的第一个处理者。

/**
 * @author chiangtaol
 * @date 2020-12-04
 * @describe 责任链管理者
 */
public class HandlerManager {
​
    private HandlerAbstract handler;
​
    public HandlerAbstract getHandler() {
        return handler;
    }
​
    public HandlerManager(){
        Handler1 handler1 = new Handler1();
        Handler2 handler2 = new Handler2();
        Handler3 handler3 = new Handler3();
        handler1.setNext(handler2);
        handler2.setNext(handler3);
​
        this.handler = handler1;
    }
}

下面测试代码:

@Test
void getHandler() {
    // 通过管理者获取一个处理者
    HandlerManager manager = new HandlerManager();
    HandlerAbstract handler = manager.getHandler();
​
    // 创建请求
    Random random = new Random();
    for (int i = 1; i < 6; i++) {
        int nextInt = random.nextInt(3)+1;
        System.out.println(String.format("第%d个请求级别为%d",i,nextInt));
        String result = handler.handleRequest(new RequestMessage(nextInt,"我要吃饭"));
        System.out.println("请求结果为:"+result);
        System.out.println("-------------------------------------");
    }
}
​
第1个请求级别为3
请求结果为:处理者3处理了请求...我要吃饭
-------------------------------------
第2个请求级别为1
请求结果为:处理者1处理了请求...我要吃饭
-------------------------------------
第3个请求级别为1
请求结果为:处理者1处理了请求...我要吃饭
-------------------------------------
第4个请求级别为3
请求结果为:处理者3处理了请求...我要吃饭
-------------------------------------
第5个请求级别为3
请求结果为:处理者3处理了请求...我要吃饭