责任链模式
概述
概念:责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
意图及组成
责任链的意图是给多个对象赋予请求的权利,从而解耦发送者和接受者,该请求链对象会在一条链上一直传递直到其中有对象处理它,一个简单的模型如下:
而在实际情况中可能会多次流转,直到找到处理对象。
责任链模式的结构主要包括Handler、ConcreteHandler和Client三部分。在责任链模式中Client像Handler提交请求,请求在多个ConcreteHandler对象形成的对象链中传递,直到该请求被处理。
- Handler(抽象处理者角色):定义出一个处理请求的接口。实现后继链。
- ConcreteHandler(具体处理者角色):处理它所负责的请求。可以访问它的后继者。如果可以处理该请求就处理。
- Client:客户端像链上的具体处理对象提交请求。
代码实例
抽象处理者角色
public abstract class Handler {
protected Handler successor;
public abstract void handleRequest();
public Handler getSuccessor() {
return successor;
}
/**
* 赋值方法,设置后继的责任对象
*/
public void setSuccessor(Handler successor) {
this.successor = successor;
}
}
具体处理者角色
public class ConcreteHandler extends Handler {
@Override
public void handleRequest() {
if(getSuccessor() != null)
{
System.out.println("放过请求");
getSuccessor().handleRequest();
}else
{
System.out.println("处理请求");
}
}
}
客户端
public class Client {
public static void main(String[] args) {
//组装责任链
Handler handler1 = new ConcreteHandler();
Handler handler2 = new ConcreteHandler();
handler1.setSuccessor(handler2);
//提交请求
handler1.handleRequest();
}
}
可以看出,客户端创建了两个处理者对象,并指定第一个处理者对象的下家是第二个处理者对象,而第二个处理者对象没有下家。然后客户端将请求传递给第一个处理者对象。
使用场景
在以下情况下可以考虑使用责任链模式: 1、处理者在运行时动态确定其实是我们在 Client 中组装的链所引起的,因为具体的职责逻辑就在链中一一对应起来; 2、因为不确定请求的具体处理者是谁,所以我们把所有可能的处理者组装成一条链,在遍历的过程中就相当于向每个处理者都提交了这个请求,等待其审查。并且在审查过程中,即使不是最终处理者,也可以进行一些请求的“包装”操作(这种功能类似于装饰者模式),例如上面例子中的签名批准; 3、处理者集合的动态指定跟上面的第1、2点类似,即在 Client 类中创建了所有可能的处理者。
不足之处
1、对于每一个请求都需要遍历职责链,性能是个问题; 2、抽象处理者 AbstractHandler 类中的 handleRequest() 方法中使用了递归,栈空间的大小也是个问题。
- Bilibili (B站)200万用户数据爬取与分析(附源码)
- 关于降低高水位线的尝试(r3笔记47天)
- 简单分析shared pool(二) (r3笔记48天)
- Python股票数据分析
- 简单分析shared pool(一) (r3笔记46天)
- 走索引扫描的慢查询(r3笔记45天)
- AR(I)MA时间序列建模过程——步骤和python代码
- 用python作信用卡欺诈预测
- 联系生活来简化sql(r3笔记第43天)
- [笔记]使用Python一步一步地来进行数据分析
- 使用 R 语言从拉勾网看数据挖掘岗位现状
- 使用strace分析exp的奇怪问题(r3笔记第41天)
- Python文本挖掘:知乎网友如何评价《人民的名义》
- 怎样做中文文本的情感分析?
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- SSH的ssh-keygen命令基本用法详解
- 图文详解Ubuntu搭建Ftp服务器的方法(包成功)
- Linux中chown与chmod两个命令的区别详解
- 解决navicat连接不上linux服务器上的mysql问题
- 增强Linux和Unix服务器安全性的方法详解
- ubuntu下没有中文输入法的解决办法
- linux查看端口是否开放的方法总结
- Linux下删除乱码或特殊字符文件的方法讲解
- Ubuntu Server下无线网卡的配置详解
- Linux中修改mysql默认编码的方法步骤
- ubuntu16.04搭建nfs服务的方法
- Ubuntu16.04搭建php5.6Web服务器环境
- Linux上通过SSH挂载远程文件系统方法详解
- Linux上创建、列出、删除Docker容器方法总结
- Centos 7.4服务器时间同步配置方法【基于NTP服务】