设计模式-责任链模式Chain of Responsibility)
一、定义
职责链模式是一种对象的行为模式。在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。
1、为请求创建一个接收此次请求对象的链
2、类型:行为型
二、适用场景
一个请求的处理需要多个对象当中的一个或几个协作处理
三、有点
请求的发送者和接收者(请求的处理)解耦
责任链可以动态的组合
四、缺点
责任链太长或者处理时间过长,影像性能
责任链有可能过多
五、类图:
职责链模式的组成:
抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义出一个方法,以设定和返回对下家的引用。这个角色通常由一个抽象类或接口实现。
具体处理者(ConcreteHandle)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
六、实例:公司请病假,1天内,项目经理批准;2天内Senior PM批准; 大于两天,医院提供病例、假条
public abstract class LeaveBaseHandler
{
protected LeaveBaseHandler successor;
public LeaveBaseHandler getSuccessor()
{
return successor;
}
public void setSuccessor(final LeaveBaseHandler successor)
{
this.successor = successor;
}
public abstract void requestLeave(int days);
}
public class OneDayLeaveConcreteHandler extends LeaveBaseHandler
{
@Override
public void requestLeave(final int days)
{
if (days <= 1)
{
System.out.println("approve one day leave");
}
else
{
super.successor.requestLeave(days);
}
}
}
public class TwoDaysLeaveConcreteHandler extends LeaveBaseHandler
{
@Override
public void requestLeave(final int days)
{
if (days > 1 && days <= 2)
{
System.out.println("approve 2 days leave");
}
else
{
super.successor.requestLeave(days);
}
}
}
public class MoreThanTwoDaysConcreteHandler extends LeaveBaseHandler
{
@Override
public void requestLeave(final int days)
{
if (days > 2)
{
System.out.println("get the record for leave from hospital");
}
}
}
public class Client
{
private static void requestLeave()
{
final LeaveBaseHandler oneDay = new OneDayLeaveConcreteHandler();
final LeaveBaseHandler twoDays = new TwoDaysLeaveConcreteHandler();
final LeaveBaseHandler moreThanTwoDays = new MoreThanTwoDaysConcreteHandler();
oneDay.setSuccessor(twoDays);
twoDays.setSuccessor(moreThanTwoDays);
oneDay.requestLeave(1);
oneDay.requestLeave(2);
oneDay.requestLeave(3);
}
public static void main(final String[] args)
{
requestLeave();
}
}
结果:
approve one day leave
approve 2 days leave
get the record for leave from hospital
如果职责链结构比较复杂,会产生很多的内存垃圾对象。
七、实例2
课程审核
1、创建批准者类
/**
* 批准者 2019/1/7.
*/
public abstract class Approver { //责任链的核心是包含一个自己。 protected可以让子类获取到它
protected Approver approver; //设置下一个批准者
public void setNextApprover(Approver approver){
this.approver = approver;
} //发布课程
public abstract void deploy(Course course);
}
2、创建ArticleApprover
public class ArticleApprover extends Approver{
@Override
public void deploy(Course course) {
if(StringUtils.isNotBlank(course.getArticle())){
System.out.println(course.getName() + "含有Article,批准");
if(approver != null){
approver.deploy(course);
}
}else{
System.out.println(course.getName() + "无Article,不批准,流程结束");
return;
}
}
}
3、创建VideoApprover
public class VideoApprover extends Approver{
@Override
public void deploy(Course course) {
if(StringUtils.isNotBlank(course.getVideo())){
System.out.println(course.getName() + "含有Video,批准");
if(approver != null){
approver.deploy(course);
}
}else{
System.out.println(course.getName() + "无Video,不批准,流程结束");
return;
}
}
}
4、创建课程Course
public class Course {
private String name;
private String article;
private String video;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getArticle() {
return article;
}
public void setArticle(String article) {
this.article = article;
}
public String getVideo() {
return video;
}
public void setVideo(String video) {
this.video = video;
}
@Override
public String toString() {
return "Course{" +
"name='" + name + '\'' +
", article='" + article + '\'' +
", video='" + video + '\'' +
'}';
}
}
5、创建测试类
public class Test {
public static void main(String[] args) {
//审核员审核article
Approver articleApprover = new ArticleApprover();
//审核员审核video
Approver videoApprover = new VideoApprover();
Course course = new Course();
course.setName("设计模式");
course.setArticle("设计模式Article");
course.setVideo("设计模式Video");
articleApprover.setNextApprover(videoApprover);
articleApprover.deploy(course);
}
}
6、输出结果

八、在源码中的应用
1、javax.servlet.Filter
Servlet中的过滤器
设计模式-责任链模式Chain of Responsibility)的更多相关文章
- C#设计模式-责任链模式(Chain of Responsibility Pattern)
引子 一个事件需要经过多个对象处理是一个挺常见的场景,譬如采购审批流程,请假流程,软件开发中的异常处理流程,web请求处理流程等各种各样的流程,可以考虑使用责任链模式来实现.现在以请假流程为例,一般公 ...
- 23种设计模式--责任链模式-Chain of Responsibility Pattern
一.责任链模式的介绍 责任链模式用简单点的话来说,将责任一步一步传下去,这就是责任,想到这个我们可以相当击鼓传花,这个是为了方便记忆,另外就是我们在项目中经常用到的审批流程等这一类的场景时我们就可以考 ...
- 乐在其中设计模式(C#) - 责任链模式(Chain of Responsibility Pattern)
原文:乐在其中设计模式(C#) - 责任链模式(Chain of Responsibility Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 责任链模式(Chain of R ...
- 二十四种设计模式:责任链模式(Chain of Responsibility Pattern)
责任链模式(Chain of Responsibility Pattern) 介绍为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求.将这些对象连成一条链,并沿着这条链传递该请求,直 ...
- 责任链模式-Chain of Responsibility(Java实现), 例2
责任链模式-Chain of Responsibility 在这种模式中,通常每个接收者都包含对另一个接收者的引用.如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推. 咱们在 ...
- 责任链模式-Chain of Responsibility(Java实现), 例1
责任链模式-Chain of Responsibility, 例1 在这种模式中,通常每个接收者都包含对另一个接收者的引用.如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推. ...
- 《JAVA设计模式》之责任链模式(Chain of Responsibility)
在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其 ...
- 责任链模式/chain of responsibility/行为型模式
职责链模式 chain of responsibility 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处 ...
- 设计模式之二十:责任链模式(Chain of Responsibility)
感觉这个设计模式和组合模式一样是一种非常巧妙的设计模式,在须要使用它的地方假设不使用这样的设计模式代码会变的非常复杂,可是这样的设计模式的基本原理又是非常easy的. 责任链模式: 通过使多个对象都有 ...
随机推荐
- MySql:触发器
触发器 一.触发器的定义: 触发器是个特殊的存储过程,不同的是,执行存储过程要使用CALL语句来调用,而触发器的执行不需要使用CALL语句来调用,也不需要手工启动,只要当一个预定的事件发生时,就会被M ...
- 框架:MVC
MVC 一.介绍 MVC是模型-视图-控制器的缩写,一种软件思想,强制性的把应用程序的输入.处理和输出分开.可以和任何的重定向能解耦. 三部分的任务说明: 视图:获取数据,显示数据 模型:处理数据 控 ...
- 中国网建提供的SMS短信发送
一个简单的发送短信的小demo 第一步: 兄弟们,首先你们去中国网建的官网去注册一个账户:网址http://sms.webchinese.cn/reg.shtml 第二步: 注册完成之后会有免费的测试 ...
- ubuntu ssh 与 Samba安装
ssh 安装:sudo apt-get install openssh-server 确认sshserver是否启动:ps -aux | grep ssh(/etc/init.d/ssh start, ...
- printf 汇总
//u32为unsigned long u32 g_u32FiveSecondCount = 0; mysprintf(TempBuf, "\r\n%ld Uart console.&quo ...
- Python中的分支结构和循环结构
一.分支结构 语法: if 条件 : .... else : .... 例子: num = int(input("输入一个整数:")) if num<=10 ...
- loadrunner如何对mysql进行增删改查
libraries.zip 地址:链接:https://pan.baidu.com/s/1kIZ2aBCOFSJ9l727MxgIKQ 密码:40vq * 说明一下,因为 lr 有很多库文件都没 ...
- ACM-ICPC 2018 焦作赛区网络预赛- G:Give Candies(费马小定理,快速幂)
There are N children in kindergarten. Miss Li bought them NNN candies. To make the process more inte ...
- linux zip tar 压缩打包命令
zip 压缩命令:(可压缩文件或目录) 压缩文件: zip new_name.zip file_name unzip name.zip 解压 压缩文件或目录: 指定解压位置: unzip na ...
- NET Core MVC中创建PDF
使用Rotativa在ASP.NET Core MVC中创建PDF 在本文中,我们将学习如何使用Rotativa.AspNetCore工具从ASP.NET Core中的视图创建PDF.如果您使用ASP ...