设计模式之美:Chain of Responsibility(职责链)
索引
意图
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它位置。
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.
Chain the receiving objects and pass the request along the chain until an object handles it.
结构

一个典型的对象结构可能如下图所示:

参与者
Handler
- 定义一个处理请求的接口。
- 实现后继链
ConcreteHandler
- 处理它所负责的请求。
- 可访问它的后继者。
- 如果可处理该请求,就处理;否则将该请求转发给它的后继者。
Client
- 向链上的具体处理者对象提交请求。
适用性
在以下情况下可以使用 Chain of Responsibility 模式:
- 有多个对象可以处理一个请求,哪个对象处理该请求运行时自动确定。
- 你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
- 可处理一个请求的对象集合应被动态指定。
效果
- 降低耦合度。对象无需知道哪个一个对象处理其请求,仅需知道对象被处理。
- 增强了给对象指派职责的灵活性。可以运行时对该链进行动态增加或修改。
相关模式
- Chain of Resposibility 常与 Composite 一起使用。一个构件的父构件可作为它的后继。
实现
实现方式(一):实现后继者链。
namespace ChainOfResponsibilityPattern.Implementation1
{
public enum RequestCategory
{
Category1,
Category2,
} public abstract class Request
{
public abstract RequestCategory Category { get; }
public bool IsHandled { get; set; }
} public class ConcreteRequest1 : Request
{
public override RequestCategory Category
{
get { return RequestCategory.Category1; }
}
} public class ConcreteRequest2 : Request
{
public override RequestCategory Category
{
get { return RequestCategory.Category2; }
}
} public abstract class Handler
{
private Handler _successor; public Handler()
{
} public Handler(Handler successor)
{
_successor = successor;
} public void Handle(Request request)
{
OnHandle(request); if (!request.IsHandled)
{
if (_successor != null)
{
// pass request to successor
_successor.Handle(request);
}
}
} protected abstract void OnHandle(Request request);
} public class ConcreteHandler1 : Handler
{
public ConcreteHandler1()
{
} public ConcreteHandler1(Handler successor)
: base(successor)
{
} protected override void OnHandle(Request request)
{
if (request.Category == RequestCategory.Category1)
{
// handle the request which category is Category1
request.IsHandled = true;
}
}
} public class ConcreteHandler2 : Handler
{
public ConcreteHandler2()
{
} public ConcreteHandler2(Handler successor)
: base(successor)
{
} protected override void OnHandle(Request request)
{
if (request.Category == RequestCategory.Category2)
{
// handle the request which category is Category2
request.IsHandled = true;
}
}
} public class Client
{
public void TestCase1()
{
Request request1 = new ConcreteRequest1();
Request request2 = new ConcreteRequest2(); Handler handler2 = new ConcreteHandler2();
Handler handler1 = new ConcreteHandler1(handler2); handler1.Handle(request1);
handler1.Handle(request2);
}
}
}
《设计模式之美》为 Dennis Gao 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。
设计模式之美:Chain of Responsibility(职责链)的更多相关文章
- 设计模式19:Chain Of Responsibility 职责链模式(行为型模式)
Chain Of Responsibility 职责链模式(行为型模式) 请求的发送者与接受者 某些对象请求的接受者可能有多种多样,变化无常…… 动机(Motivation) 在软件构建过程中,一个请 ...
- 设计模式学习笔记——Chain of Responsibility职责链模式
重点在链.一条链,如果本节点处理不了,则传递给下一个节点处理. 关键是如何传给下一个节点? 主要是由本节点决定传给哪一个节点. public class Client { public static ...
- Java设计模式(二十一):职责链模式
职责链模式(Chain Of Responsibility Pattern) 职责链模式(Chain Of Responsibility Pattern):属于对象的行为模式.使多个对象都有机会处理请 ...
- 设计模式(二十四)——职责链模式(SpringMVC源码分析)
1 学校 OA 系统的采购审批项目:需求是 采购员采购教学器材 1) 如果金额 小于等于 5000, 由教学主任审批 (0<=x<=5000) 2) 如果金额 小于等于 10000, ...
- [Python设计模式] 第24章 加薪审批——职责链模式
github地址:https://github.com/cheesezh/python_design_patterns 题目 用程序模拟以下情景 员工向经理发起加薪申请,经理无权决定,需要向总监汇报, ...
- python 设计模式之 (Chain of Responsibility)责任链模式
#写在前面 对于每一种设计模式,如果不理解它的原理和结构,是写不出例子来的.所以弄明白很重要. 等过完这段浑浑噩噩的日子,我要找个遍地开花的地方开怀大笑一场 #责任链模式定义 简书上一网友就把这个定义 ...
- 设计模式(一)Chain Of Responsibility责任链模式
设计模式篇章,源于网课的学习,以及个人的整理 在我们接收用户提交的字符时,常常会使用到过滤,在学习责任链模式前,我们是这样做的 1.定义一个类 public class MsgProcesser { ...
- 设计模式(13)--Chain of Responsibility(责任链模式)--行为型
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.模式定义: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一 ...
- 设计模式C++学习笔记之十七(Chain of Responsibility责任链模式)
17.1.解释 概念:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. main(),客户 IWom ...
- go语言设计模式之Chain Of Responsibility(责任链)
ChainOfResponsibility.go package ChainOfResponsibility import ( "fmt" "io" " ...
随机推荐
- 问题Initial SessionFactory creation failed.org.hibernate.HibernateException: /hibernate.cfg.xml not found解决方法
问题Initial SessionFactory creation failed.org.hibernate.HibernateException: /hibernate.cfg.xml not fo ...
- thinkphp加载 和url_model
1.加载thinkphp.php requrie('./ThinkPHP/ThinkPHP.php'); 2.加载核心文件 ./thinkPHP/LIB/core 3.加载项目的文件 分析URL 调用 ...
- sql Server中SET QUOTED_IDENTIFIER的使用
在存储过程中经常会有 Sql代码 SET QUOTED_IDENTIFIER on SET QUOTED_IDENTIFIER off 这样的语句,那么SET QUOTED_IDENTIFIER到 ...
- codeforces731C Socks
C. Socks time limit per test 2 seconds memory limit per test 256 megabytes input standard input outp ...
- struts2各个jar包的作用
---------------------------------------------------struts2核心jar包------------------------------------ ...
- DrawingControl控件在Add Page时报故障的问题
Visio二次开发用到了Drawing Control控件.在控件上添加新页面时,visual编译器报内存保护故障“尝试读取或写入受保护的内存.这通常指示其他内存已损坏.”,这个问题困扰了我很久,最后 ...
- C#语法灵活运用之排列组合算法
今天群里有朋友求一个排列组合算法,题目是给定长度,输出所有指定字母的组合. 如指定字母a.b.c.d.e.f,长度为2,则结果应为:aa.ab.ac ... ef.ff. 有朋友给出算法,很有特色: ...
- flash项目优化总结
swc中的类如果没有在项目中没有被申明,在编译时就不会被编译进swf中,这样一些swc中的类和资源类如果不用了,只要不被声明就不会占用swf大小了.
- Linux 下安装 jdk压缩包
按 esc 退出 记得 输入 :q 记得 : Linux下安装jdk 把压缩文件放在 桌面的soft 下 在usr目录下新建文件夹Java,把文件复制到 usr/java 更改下路径! 3 ...
- CSS3--选择器
子元素选择器: div>p{background:yellow:} 相邻的后兄弟选择器(必须相邻) h1+p{padding-top:20px:} 后兄弟选择器(同级的当前元素后面的元素) di ...