设计模式——职责链模式(附代码示例)
一. 传统方式
以学校采购审批为例,不同金额的采购需要不同人员的审批
1. 传统方式解决
收到请求后,通过不同的金额调用对应的审批方法
2. 传统方式存在问题
Client会使用到分支判断(比如switch)来对不同的采购请求处理, 这样就存在如下问题:
(1)如果各个级别的人员审批金额发生变化,客户端的也需要变化
(2)客户端必须明确知道有多少个审批级别和访问
这样对一个采购请求进行处理和Approver(审批人)就存在强耦合关系,不利于代码的扩展和维护。故引出职责链模式。
二. 职责链模式
1. 概念
职责链模式(Chain of Responsibility Pattern),又叫责任链模式,为请求创建了一个接收者对象的链,属于行为型模式。这种模式对请求的发送者和接收者进行解耦。
职责链模式通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
职责链模式使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
2. 职责链模式原理类图
Handler:抽象的处理者,定义了一个处理请求的接口,同时含有另外Handler
ConcreteHandlerA, B:具体的处理者,处理它自己负责的请求,可以访问它的后继者 (即下一个处理者),如果可以处理当前请求则处理,否则就将该请求交个后继者去处理,从而形成一个职责链
Request:含有很多属性,表示一个请求
3. 代码示例
类图
PurchaseRequest类,表示一个请求
public class PurchaseRequest {private int type;//请求类型private float price = 0.0f;private int id = 0;public PurchaseRequest(int type, float price, int id) {this.type = type;this.price = price;this.id = id;}public int getType() {return type;}public float getPrice() {return price;}public int getId() {return id;}
}
Approver抽象类,抽象的处理者,定义了一个处理请求的接口,同时含有另外Approver
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);
}
DepartmentApprove类,继承Approver抽象类,表示系领导处理
public class DepartmentApprove extends Approver{public DepartmentApprove(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if(purchaseRequest.getPrice()<=5000){System.out.println("请求编号:"+purchaseRequest.getId()+"被"+this.name+"处理");}else {approver.processRequest(purchaseRequest);}}
}
CollegeApprove类,继承Approver抽象类,表示院领导处理
public class CollegeApprove extends Approver{public CollegeApprove(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if(purchaseRequest.getPrice()>=5000&&purchaseRequest.getPrice()<=50000){System.out.println("请求编号:"+purchaseRequest.getId()+"被"+this.name+"处理");}else {approver.processRequest(purchaseRequest);}}
}
SchoolApprove类,继承Approver抽象类,表示校领导处理
public class SchoolApprove extends Approver{public SchoolApprove(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if(purchaseRequest.getPrice()>=500000){System.out.println("请求编号:"+purchaseRequest.getId()+"被"+this.name+"处理");}}
}
Client类,模拟学校处理审批过程
public class Client {public static void main(String[] args) {PurchaseRequest purchaseRequest1 = new PurchaseRequest(1, 1000, 1);PurchaseRequest purchaseRequest2 = new PurchaseRequest(2, 50000, 2);PurchaseRequest purchaseRequest3 = new PurchaseRequest(2, 500001, 3);DepartmentApprove departmentApprove = new DepartmentApprove("系领导");CollegeApprove collegeApprove = new CollegeApprove("院领导");SchoolApprove schoolApprove = new SchoolApprove("校领导");//设置下一级处理人departmentApprove.setApprover(collegeApprove);collegeApprove.setApprover(schoolApprove);//都从系领导开始处理departmentApprove.processRequest(purchaseRequest1);departmentApprove.processRequest(purchaseRequest2);departmentApprove.processRequest(purchaseRequest3);}
}
输出结果
三. 总结
1. 优点
将请求和处理分开,实现解耦,提高系统的灵活性
简化了对象,使对象不需要知道链的结构
2. 不足
性能会受到影响,特别是在链比较长的时候,因此需控制链中最大节点数量,一般通过在Handler中设置一个最大节点数量,在setNext()方法中判断是否已经超过阀值,超过则不允许该链建立,避免出现超长链无意识地破坏系统性能
调试不方便,采用了类似递归的方式,调试时逻辑可能比较复杂
3. 适用场景
多个对象可以处理同一个请求时,比如:多级请求、请假/加薪等审批流程、Java Web中Tomcat对Encoding的处理、拦截器等
设计模式——职责链模式(附代码示例)相关推荐
- 第二十章 Caché 设计模式 职责链模式
文章目录 第二十章 Caché 设计模式 职责链模式 定义 优点 缺点 结构图 描述 完整示例 请求类 抽象责任类 实现责任类 调用 思考 第二十章 Caché 设计模式 职责链模式 定义 使多个对象 ...
- Python设计模式-职责链模式
Python设计模式-职责链模式 代码基于3.5.2,代码如下; #coding:utf-8 #职责链模式class Handler():def __init__(self):self.success ...
- C++设计模式-职责链模式
目录 基本概念 代码与实例 在哪种地方使用 基本概念 职责链模式(Chain of Responsibility):时多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这个对象连 ...
- PHP设计模式——职责链模式
声明:本系列博客参考资料<大话设计模式>,作者程杰. 职责链模式(又叫责任链模式)包含了一些命令对象和一些处理对象,每个处理对象决定它能处理那些命令对象,它也知道应该把自己不能处理的命令对 ...
- 设计模式|职责链模式--流程状态审批(枚举实现)
流程审批 在实际的项目中,我们经常会涉及到某个对象实体的状态转换,比如合同审批,请假审批,订单流程状态流转,由于本文不涉及工作流(Activiti,Zeebe)的介绍,只是介绍职责链模式的设计模式,因 ...
- 设计模式-职责链模式(责任链模式)
职责链模式 将一系列类似却职责不全相同的对象 像链表一样 链接起来,当有一个请求,需要找能处理请求的处理对象,针对每一个请求如果都需要记住能处理它的对象是非常麻烦的,于是可以通过这条职责链,一路暴力寻 ...
- C++设计模式——职责链模式(responsibility chain pattern)
一.原理讲解 1.1意图 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 1.2应用场景 有多个对象可以处 ...
- 设计模式---职责链模式(Chain of Responsibility Pattern)
目录 1.学校 OA系统采购审批需求 2.传统方式解决审批流程 3.传统 方式 问题分析 4.职责链模式基本介绍 5.职责链模式原理类图 6.职责链模式解决OA采购审批 7.职责链模式在SpringM ...
- 设计模式-职责链模式
1.定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,直到对象处理它为止. 相信大家都写过if...else或者swit ...
最新文章
- [转]启动Tomcat提示:指定的服务未安装
- 导入Java文件还是class文件_java程序运行的时候,是把所有的class文件都加载到内存吗?还是用的什么加载什么?...
- 使用google开源框架Exoplayer开发自定义播放器
- 请求包含(Include)和请求转发(Forward)
- oracle如何创建一个定时任务,怎么创建定时任务
- foldable bike
- 【echarts】echarts开发详解
- 1185 城市名排序
- [看书笔记]《深入java虚拟机》——java体系结构(二)
- linux是什么样的_您的Linux设置是什么样的?
- 基于JAVA+SpringMVC+Mybatis+MYSQL的生活质量衡量系统
- redhat6 本地 yum源配置方法
- 行政区划编码转换区域名工具类
- 电信吉比特光纤猫虚拟服务器设置,吉比特光纤猫内置wifi怎样设置上网
- 光猫超级帐号密码,重置光猫获取超级帐号密码
- cad化工设备绘图_auto cad在化工设备制图中的应用 ——致初学cad绘图者.ppt
- Excel日期运算单,多条件求和与计数
- android 5.1 随机IMEI号
- 乐普生物下周三上市:最高募资近10亿港元 年亏将超10亿
- could not locate named parameter 的解决方法