设计模式整理(三)责任链模式

责任链模式

  • 责任链模式的定义
    将请求发送者与多个请求处理者解耦,通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。

  • 责任链模式的适用场景
    当一个事件需要经过层层处理时, 可以采用这种设计模式, 比如: 请假审批(一级一级向上申请)

  • 责任链模式的优点
    1、降低耦合度。它将请求的发送者和接收者解耦。
    2、简化了对象。使得对象不需要知道链的结构。
    3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
    4、增加新的请求处理类很方便。

  • 责任链模式的缺点
    1、不能保证请求一定被接收。
    2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
    3、可能不容易观察运行时的特征,有碍于除错。


责任链模式的实现

  • 项目结构

创建一个A处理后调用B, B处理后调用C, C处理后最终响应结果的调用链
image.png

  • 创建spring容器操作工具类
package cn.zack.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component("applicationUtils")
public class ApplicationUtils implements ApplicationContextAware {
    public static ApplicationContext context = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    public static ApplicationContext getContext() {
        return context;
    }
}
  • 创建抽象类
package cn.zack.handler;

import cn.zack.utils.ApplicationUtils;
import org.springframework.web.client.RestTemplate;

/**
 * 抽象调用链处理器
 */
public abstract class AbstractHandler<T, U> {

    /**
     * 所有子类中需要注入使用的bean, 都可以在抽象类中统一注入
     */
    RestTemplate restTemplate;

    /**
     * 由于抽象类描述的不是一个具体的类, 不能被spring容器管理, 不能实例化
     * 则在此构造器中通过ApplicationContext从spring容器中获取bean的实例进行注入
     * 则此抽象类的子类必须使用@DependsOn注解:
     * 保证ApplicationUtils在使用子类之前实例化
     * 保证ApplicationUtils在子类之后销毁
     */
    public AbstractHandler() {
        this.restTemplate = ApplicationUtils.getContext().getBean(RestTemplate.class);
    }

    /**
     * 抽象任务处理器, 作用与本包以及子类
     */
    protected AbstractHandler<T, U> successor;

    /**
     * 设置下一个处理器
     *
     * @param successor
     */
    public abstract void setNextSuccessor(AbstractHandler<T, U> successor);

    /**
     * 具体的业务处理方法
     *
     * @param msg
     */
    public abstract U handler(T msg);
}
  • 创建抽象类的子类A
package cn.zack.handler;

import org.springframework.context.annotation.DependsOn;

@DependsOn("applicationUtils")
public class Handler_A<T, U> extends AbstractHandler<T, U> {
    private AbstractHandler<T, U> successor;

    public Handler_A() {
        super();
    }

    @Override
    public void setNextSuccessor(AbstractHandler<T, U> successor) {
        this.successor = successor;
    }

    @Override
    public U handler(T msg) {
        System.out.println("处理者A无法处理, 交给下一级处理-----, 消息内容为: " + msg);
        // 调用链继续
        U handler = this.successor.handler(msg);
        System.out.println("处理者A调用下一级得到的处理结果:" + handler);
        return handler;
    }
}
  • 创建抽象类的子类B
package cn.zack.handler;

import org.springframework.context.annotation.DependsOn;

@DependsOn("applicationUtils")
public class Handler_B<T, U> extends AbstractHandler<T, U> {
    private AbstractHandler<T, U> successor;

    public Handler_B() {
        super();
    }

    @Override
    public void setNextSuccessor(AbstractHandler<T, U> successor) {
        this.successor = successor;
    }

    @Override
    public U handler(T msg) {
        System.out.println("处理者B无法处理, 交给下一级处理-----, 消息内容为: " + msg);
        // 调用链继续
        U handler = this.successor.handler(msg);
        System.out.println("处理者B调用下一级得到的处理结果:" + handler);
        return handler;
    }
}
  • 创建抽象类的子类C
package cn.zack.handler;

import org.springframework.context.annotation.DependsOn;

@DependsOn("applicationUtils")
public class Handler_C<T, U> extends AbstractHandler<T, U> {
    private AbstractHandler<T, U> successor;

    public Handler_C() {
        super();
    }

    @Override
    public void setNextSuccessor(AbstractHandler<T, U> successor) {
        this.successor = successor;
    }

    @Override
    public U handler(T t) {
        // 使用抽象父类中注入的bean
        restTemplate.postForEntity("http://127.0.0.1/a/b", null, null);
        System.out.println("处理者C处理完成, 消息内容为: " + t);
        // 调用链结束
        return (U) "3333";
    }
}
  • 创建调用链
package cn.zack.controller;

import cn.zack.handler.Handler_A;
import cn.zack.handler.Handler_B;
import cn.zack.handler.Handler_C;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(path = "/test")
public class DemoController {

    @RequestMapping(path = "/fun", method = RequestMethod.GET)
    public void test() {
        Handler_A<String, String> a = new Handler_A<>();
        Handler_B<String, String> b = new Handler_B<>();
        Handler_C<String, String> c = new Handler_C<>();
        // 为每一级别指定下一级的执行者
        b.setNextSuccessor(c);
        a.setNextSuccessor(b);
        String o = a.handler("aaa");
        System.out.println(o);
    }
}