设计模式之美: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" " ...
随机推荐
- vi 使用
1)命令 gf ,可以从光标指定的文件位置打开对应文件 :bd回来 2)http://www.cnblogs.com/wangkangluo1/archive/2012/04/12/244495 ...
- ghost系统到硬盘完后,重启进入winxp安装的画面变成了蓝屏
ghost系统到硬盘完后,重启进入winxp安装的画面变成了蓝屏 原因分析: 一.系统集成的驱动和主板不兼容 这种原因引起的故障在部份品牌机上较常见,主要症状是系统能正常安装完成,但完成后重启进入系 ...
- ios 学习总结之动画(转)
转自:http://blog.sina.com.cn/s/blog_a85effc301012wu4.html UIView的,翻转.旋转,偏移,翻页,缩放,取反的动画效果 翻转的动画 //开始动 ...
- ca des key crt scr
openssl genrsa -des3 -out domain.key 1024 openssl req -new -key domain.key -out domain.csr openssl r ...
- ide编辑器
http://wowubuntu.com/markdown/#editor https://netbeans.org/downloads/start.html?platform=windows& ...
- 高版本Chrome不支持showModalDialog
高版本Chrome不支持window.showModalDialog,可用window.open代替 var url = "https://www.baidu.com"; var ...
- 写shell脚本速查笔记
linux shell脚本的语法蛋疼,而且对于java开发人员来说又不常用,常常是学了一次等到下次用的时候又忘记了.因此制作这个速查笔记,用于要写shell脚本时快速回忆&速查. 获取当前脚本 ...
- jquery学习--属性操作
学习jquery很长一段时间了,知道对属性操作的方式为: $("#xx1").attr("xx2"); //获取属性值 $("#xx1"). ...
- 移动端布局,div按比例布局,宽度为百分比,高度和宽度一样,即让div为正方形
http://codepen.io/airen/details/XbVBZo <div><span>1</span></div> <div> ...
- POJ 2352Stars 树状数组
Stars Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 42898 Accepted: 18664 Descripti ...