《设计模式详解》行为型模式 - 职责链模式
职责链模式
- 6.4 职责链模式
- 6.4.1 概述
- 6.4.2 结构
- 6.4.3 案例实现
- 6.4.4 优缺点
- 6.4.5 JavaWeb 源码 - FilterChain
完整的笔记目录:《设计模式详解》笔记目录,欢迎指点!
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式:
- 类行为模式:采用继承机制来在类间分派行为
- 对象行为模式:采用组合或聚合在对象间分配行为
由于组合关系或聚合关系比继承关系耦合度低,满足 “合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。
行为型模式分为:
- 模板方法模式
- 策略模式
- 命令模式
- 职责链模式
- 状态模式
- 观察者模式
- 中介者模式
- 迭代器模式
- 访问者模式
- 备忘录模式
- 解释器模式
以上 11 种行为型模式,除了模板方法模式和解释器模式是类行为型模式,其他的全部属于对象行为型模式。
6.4 职责链模式
6.4.1 概述
在现实生活中,常常会出现这样的事例:一个请求有多个对象可以处理,但每个对象的处理条件或权限不同。例如,公司员工请假,可批假的领导有【部门负责人】、【副总经理】、【总经理】等,但每个领导能批准的天数不同,员工必须根据自己要请假的天数去找不同的领导签名,也就是说员工必须记住每个领导的姓名、电话和地址等信息,这增加了难度。
职责链模式:又名责任链模式,为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。
6.4.2 结构
职责链模式主要包含以下角色:
- 抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
- 具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
- 客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。
6.4.3 案例实现
【例】现需要开发一个请假流程控制系统。
请假一天以下只需要小组长同意即可,请假 1 ~ 3 天的假还需要部门经理同意,请 3 ~ 7 天还需要总经理同意才行。
请假条类:
@Getter
public class LeaveRequest {// 姓名private String name;// 请假天数private int num;// 请假内容private String content;public LeaveRequest(String name, int num, String content) {this.name = name;this.num = num;this.content = content;}
}
抽象处理者:
public abstract class Handler {protected final static int NUM_ONE = 1;protected final static int NUM_THREE = 3;protected final static int NUM_SEVEN = 7;// 该领导处理的请求天数区间private int numStart;private int numEnd;// 声明后续者(声明上级领导)private Handler nextHandler;public Handler(int numStart) {this.numStart = numStart;}public Handler(int numStart, int numEnd) {this.numStart = numStart;this.numEnd = numEnd;}// 设置上级领导对象public void setNextHandler(Handler nextHandler) {this.nextHandler = nextHandler;}// 各级领导处理请求条的方法protected abstract void handleLeave(LeaveRequest leave);// 提交请求条public final void submit(LeaveRequest leave) {// 该领导进行审批this.handleLeave(leave);if (this.nextHandler != null && leave.getNum() > this.numEnd) {// 提交给上级领导进行审批this.nextHandler.submit(leave);} else {System.out.println("流程结束!");}}
}
具体处理者:小组长、部门经理、总经理
/*** 小组长类,处理1天的假条*/
public class GroupLeader extends Handler {public GroupLeader() {super(0, Handler.NUM_ONE);}protected void handleLeave(LeaveRequest leave) {System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");System.out.println("小组长审批:同意");}
}/*** 部门经理类,处理1~3天的假条*/
public class Manager extends Handler {public Manager() {super(Handler.NUM_ONE, Handler.NUM_THREE);}protected void handleLeave(LeaveRequest leave) {System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");System.out.println("部门经理审批:同意");}
}/*** 经理类,处理3-7天的假条*/
public class GeneralManager extends Handler {public GeneralManager() {super(Handler.NUM_THREE, Handler.NUM_SEVEN);}protected void handleLeave(LeaveRequest leave) {System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");System.out.println("总经理审批:同意");}
}
测试类:
public class Client {public static void main(String[] args) {// 创建一个请假条对象LeaveRequest leave = new LeaveRequest("小明", 7, "身体不适");// 创建各级领导对象GroupLeader groupLeader = new GroupLeader(); // 小组长Manager manager = new Manager(); // 部门经理GeneralManager generalManager = new GeneralManager(); // 总经理// 设置处理者链groupLeader.setNextHandler(manager);manager.setNextHandler(generalManager);// 小明提交请假申请groupLeader.submit(leave);}
}
6.4.4 优缺点
优点:
降低了对象之间的耦合度,该模式降低了请求发送者和接收者的耦合度。
增强了系统的可扩展性,可以根据需要增加新的请求处理类,满足开闭原则。
增强了给对象指派职责的灵活性,当工作流程发生变化,可以动态地改变链内的成员或者修改它们的次序,也可动态地新增或者删除责任。
责任链简化了对象之间的连接,一个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。
责任分担,每个类只需要处理自己该处理的工作,不能处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。
缺点:
- 不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。
- 对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。
- 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。
6.4.5 JavaWeb 源码 - FilterChain
在 JavaWeb 应用开发中,FilterChain 是职责链模式的典型应用,以下是 Filter 的模拟实现分析:
模拟 Web 请求 Request 以及 Web 响应 Response:
public interface Request{}public interface Response{}
模拟 Web 过滤器 Filter:
public interface Filter {void doFilter(Request req,Response res,FilterChain c);
}
模拟实现具体过滤器:
public class FirstFilter implements Filter {@Overridepublic void doFilter(Request request, Response response, FilterChain chain) {System.out.println("过滤器1 前置处理");// 先执行所有request再倒序执行所有responsechain.doFilter(request, response);System.out.println("过滤器1 后置处理");}
}public class SecondFilter implements Filter {@Overridepublic void doFilter(Request request, Response response, FilterChain chain) {System.out.println("过滤器2 前置处理");// 先执行所有request再倒序执行所有responsechain.doFilter(request, response);System.out.println("过滤器2 后置处理");}
}
模拟实现过滤器链 FilterChain:
public class FilterChain {private List<Filter> filters = new ArrayList<>();private int index = 0;// 链式调用public FilterChain addFilter(Filter filter) {this.filters.add(filter);return this;}// 过滤操作public void doFilter(Request request, Response response) {if (index == filters.size()) {return;}Filter filter = filters.get(index);index++;filter.doFilter(request, response, this);}
}
测试类:
public class Client {public static void main(String[] args) {Request req = null;Response res = null ;FilterChain filterChain = new FilterChain();filterChain.addFilter(new FirstFilter()).addFilter(new SecondFilter());filterChain.doFilter(req,res);}
}
过滤器1 前置处理
过滤器2 前置处理
过滤器2 后置处理
过滤器1 后置处理
《设计模式详解》行为型模式 - 职责链模式相关推荐
- 责任链模式(职责链模式)(Chain of Responsibility Pattern)
学校OA 系统的采购审批项目:需求是 采购员采购教学器材 如果金额小于等于5000, 由教学主任审批(0<=x<=5000) 如果金额小于等于10000, 由院长审批(5000<x& ...
- 15、设计模式-行为型模式-职责链模式
职责链模式 很多情况下,在一个软件系统中可以处理某个请求的对象不止一个,例如SCM系统中的采购 单审批,主任.副董事长.董事长和董事会都可以处理采购单,他们可以构成一条处理采购 单的链式结构,采购单沿 ...
- Java设计模式(备忘录模式-解释器模式-状态模式-策略模式-职责链模式)
Java设计模式Ⅶ 1.备忘录模式 1.1 备忘录模式概述 1.2 代码理解 2.解释器模式 2.1 解释器模式概述 3.状态模式 3.1 状态模式概述 3.2 代码理解 4.策略模式 4.1 策略模 ...
- 【设计模式系列】行为型之责任链模式
目录 背景 理论 实践 总结 背景 责任链模式,小编在自己项目迭代过程也参与了维护和设计实现:本篇博文主要针对该设计模型进行总结和实践: 简单举例日常生活或者工作中能够接触的责任链模式场景:采购审批流 ...
- 设计模式详解(四)抽象工厂模式
文章目录 1. 简介 2. 代码实例 3. 抽象工厂的优缺点 1. 简介 定义:为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类 与工厂方法模式不同(工厂方法的升级,在工厂方法模式 ...
- 设计模式C++实现(14)——职责链模式
职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止.其思想很简单,考虑员工要求加薪.公司的管理者 ...
- JS模式--职责链模式
职责链模式的定义:使用多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链, 并沿着这条链条传递下去,直到有一个对象处理它为止. var order500 = f ...
- 5.js模式-职责链模式
1. 职责链模式 将对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止. var chain = function(fn){ this.fn = fn; this.successor = ...
- 设计模式详解(二十)——迭代器模式
一.场景问题 在激烈的市场竞争中,为了提高自己的硬实力,A公司和B公司决定合并.现在目前二者的员工信息都存放在不同的数据库中,且存储的方式不同,请设计出统一的读取所有员工(A.B公司之和)信息的接口. ...
最新文章
- 引用 提高开发水平的几项必备技术
- Word自定义多级符号方法
- x264各个版本下载
- C++_向函数传递对象
- Spring MVC 向前台页面传值-ModelAndView
- 定位低效SQL与不同的Extra类型(转载)
- Oracle及Oracle客户端、PLSQL安装的一些问题
- python播放音乐-python 模拟(简易)音乐播放器
- IOS系统定时APP
- 25. PHP 文件处理
- 通过ln链接目录到目标
- GD32F103基础教程—硬件介绍(四)
- 抖音视频什么时候投放dou+最好,dou+投放实战总结:国仁网络资讯
- Python高级数据处理与可视化
- ansys 英文路径 安装失败
- linux dd 错,dd命令错误写入设备上没有剩余空间[关闭](dd command error writing No space left on device [closed])...
- Java打印一个正三角形
- 今日说“法”:FPGA芯片如何选型?
- bootloader介绍
- 给大家分享下仿QQ消息页面横向滑出菜单,Item内容较多的情况
热门文章
- 见过一些能力非常强的但创业总是失败
- 为什么大家都会往大城市跑
- Seeing this, many people find it incredible
- 【go】atmoic.Value
- pl/sql 测试函数_如何在SQL单元测试中使用伪函数?
- mercurial和svn_DBA Mercurial简介–分支和合并
- Assembly generation failed Referenced assembly ‘xxx’ does not have a strong name
- python爬虫案例-乌托家家具公司数据爬取
- css元素穿透。 pointer-events: none;
- k8s的应用打包工具Helm