当前位置: 首页 > news >正文

设计模式之职责链模式

什么是职责链模式

    职责链模式是避免请求发送者与接受者耦合在一起,让多个对象都可以接受到请求,从而将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理为止。
    职责链模式包含以下几个角色:
        Handler(抽象处理者):定义处理请求的接口,一般是抽象类。由于不同的具体处理类处理请求的方式不同,因此在其中定义抽象处理请求的方法。因为每一个处理这的下家还是处理者,因此在抽象处理者中定义一个抽象处理者类型的对象作为下家的引用。
        ConcreteHandler(具体处理者):是抽象处理者的子类,实现了抽象处理者中定义的抽象方法用于处理用户请求。具体处理者有两大作用:一是处理请求,不同的具体处理者以不同的形式实现抽象处理者的方法。二是转发请求,当前处理类可将请求转发给下家。
    职责链模式可以分为纯的职责链模式和不纯的职责链模式:
        纯的职责链模式:要求具体处理者只能在两个行为中选择一个,要么承担全部责任,要么将责任转发给下家,不允许出现一个具体处理者承担了一部分或全部责任还要将责任转发给下家。
        不纯的职责链模式:允许请求被一个具体处理者处理部分或全部后在转发给下家,也可以不被任何处理者所处理。

职责链模式的优缺点

优点

  1. 一个对象无需知道是其他哪个对象处理请求,降低了系统耦合。
  2. 请求处理对象只需维护一个指向下家的的引用,简化对象的相互连接。
  3. 给对象分派职责时更加灵活,可以通过在运行时对该链进行动态增加或修改改变处理请求的职责。
  4. 增加新的处理请求时无需修改代码,符合开闭原则。

缺点

  1. 不保证每个请求都会被处理。
  2. 太长的职责链涉及更多的处理对象,会降低系统性能。
  3. 可能会造成循环调用陷入死循环。

职责链模式的应用场景

  1. 有多个对象可以处理同一个请求,具体哪个对象处理在运行时决定。
  2. 不明确接受者的情况下,向多个对象中的一个提交请求。
  3. 可动态指定一组对象处理请求,客户端可以动态创建职责链处理请求,还可以改变处理请求的顺序。

职责链模式的案例

// 请求对象
public class PurchaseRequest implements Serializable {private int type = 0;private float price = 0.0f;private int id = 0;}// 抽象处理者
public abstract class Approver {Approver approver;String name;public Approver(String name) {this.name = name;}public void setApprover(Approver approver) {this.approver = approver;}public abstract void processRequest(PurchaseRequest purchaseRequest);}// 具体处理者
public class CollegeApprover extends Approver {public CollegeApprover(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if (purchaseRequest.getPrice() < 5000 && purchaseRequest.getPrice() <= 10000) {System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");} else {approver.processRequest(purchaseRequest);}}
}public class DepartmentApprover extends Approver {public DepartmentApprover(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if (purchaseRequest.getPrice() <= 5000) {System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");} else {approver.processRequest(purchaseRequest);}}}public class SchoolMasterApprover extends Approver {public SchoolMasterApprover(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if (purchaseRequest.getPrice() > 30000) {System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");} else {approver.processRequest(purchaseRequest);}}
}public class ViceSchoolMasterApprover extends Approver {public ViceSchoolMasterApprover(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if (purchaseRequest.getPrice() < 10000 && purchaseRequest.getPrice() <= 30000) {System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");} else {approver.processRequest(purchaseRequest);}}
}

在这里插入图片描述

职责链模式在源码中的应用

org.apache.ibatis.plugin.InterceptorChain

// 在mybatis源码中,添加拦截器就是使用责任链模式
// pluginAll 通过这个方法可以添加定义好的拦截器实现
// 通过遍历 getInterceptors 就可以去请求每一个定义好的拦截器类
public class InterceptorChain {private final List<Interceptor> interceptors = new ArrayList<>();public Object pluginAll(Object target) {for (Interceptor interceptor : interceptors) {target = interceptor.plugin(target);}return target;}public void addInterceptor(Interceptor interceptor) {interceptors.add(interceptor);}public List<Interceptor> getInterceptors() {return Collections.unmodifiableList(interceptors);}}

http://www.lryc.cn/news/602.html

相关文章:

  • MySQL入门篇-MySQL 8.0 延迟复制
  • FPGA时序约束与分析 --- 实例教程(1)
  • go深拷贝和浅拷贝
  • linux网络系统层面的配置、管理及操作命令汇总
  • R数据分析:孟德尔随机化中介的原理和实操
  • 【C++】 类和对象 (下)
  • asp获取毫秒时间戳的方法 asp获取13位时间戳的方案
  • Python基础篇(十五)-- Python程序接入MySQL数据库
  • 程序员不得不知道的 API 接口常识
  • 【项目精选】基于Java的银行排号系统的设计与实现
  • 前端 基于 vue-simple-uploader 实现大文件断点续传和分片上传
  • 解决报错: ERR! code 128npm ERR! An unknown git error occurred
  • 聊城高新技术企业认定7项需要注意的问题 山东同邦科技分享
  • 菊乐食品更新IPO招股书:收入依赖单一地区,规模不及认养一头牛
  • Elasticsearch安装IK分词器、配置自定义分词词库
  • Linux嵌入式开发——shell脚本
  • CV【5】:Layer normalization
  • 跳跃游戏 II 解析
  • 易基因|猪肠道组织的表观基因组功能注释增强对复杂性状和人类疾病的生物学解释:Nature子刊
  • 01- NumPy 数据库 (机器学习)
  • RapperBot僵尸网络最新进化:删除恶意软件后仍能访问主机
  • 拦截器interceptor总结
  • 轻松实现微信小程序上传多文件/图片到腾讯云对象存储COS(免费额度)
  • Golang中defer和return的执行顺序 + 相关测试题(面试常考)
  • 谁说菜鸟不会数据分析,不用Python,不用代码也轻松搞定
  • php mysql保健品购物商城系统
  • Vue3电商项目实战-首页模块6【22-首页主体-补充-vue动画、23-首页主体-面板骨架效果、4-首页主体-组件数据懒加载、25-首页主体-热门品牌】
  • linux 使用
  • 基于遗传算法的微电网调度(风、光、蓄电池、微型燃气轮机)(Matlab代码实现)
  • 方向导数与梯度下降