《图解设计模式》读书笔记6-2 Chain of Responsibility模式
1. 简介
Chain of Responsibility模式是责任链模式,模式的核心就是转移责任。就好比你要去政府部门办事,A部门说你去B部门问问,B部门说你去C部门问问,C部门说我们不管...在找到正确的部门解决问题之前,这些部门一直在踢皮球。
在程序中,确实需要这样的场景:将多个对象组成一个责任链,一个请求过来了,按照它们在责任链上的顺序一个一个找出到底由谁来负责。
这个模式的好处在于弱化请求方和处理方的关联关系,让双方都可以成为独立复用的组件。
2. 示例程序
类图

代码
Trouble类是表示问题的类,其属性nubmer是问题编号。
Support以及其子类表示解决问题的类,Support是抽象父类,具体的Support类表示解决特定问题的类。
public class Trouble {
private int number; // 问题编号
public Trouble(int number) { // 生成问题
this.number = number;
}
public int getNumber() { // 获取问题编号
return number;
}
public String toString() { // 代表问题的字符串
return "[Trouble " + number + "]";
}
}
//解决问题的抽象父类
public abstract class Support {
private String name;
private Support next;
public Support(String name) {
this.name = name;
}
public Support setNext(Support next) {
this.next = next;
return next;
}
//定义解决问题的步骤
// 其中使用了抽象方法resolve,这个方法由子类实现,这是Template Method方法的体现。
public void support(Trouble trouble) {
if (resolve(trouble)) {
done(trouble);
} else if (next != null) {
next.support(trouble);
} else {
fail(trouble);
}
}
public String toString() {
return "[" + name + "]";
}
protected abstract boolean resolve(Trouble trouble);
protected void done(Trouble trouble) {
System.out.println(trouble + " is resolved by " + this + ".");
}
protected void fail(Trouble trouble) {
System.out.println(trouble + " cannot be resolved.");
}
}
//什么问题都不解决
public class NoSupport extends Support {
public NoSupport(String name) {
super(name);
}
protected boolean resolve(Trouble trouble) { // 解决问题的方法
return false; // 自己什么也不处理
}
}
// 可以解决编号小于limit的问题
public class LimitSupport extends Support {
private int limit;
public LimitSupport(String name, int limit) { // 构造函数
super(name);
this.limit = limit;
}
protected boolean resolve(Trouble trouble) { // 解决问题的方法
if (trouble.getNumber() < limit) {
return true;
} else {
return false;
}
}
}
//解决编号为奇数的问题
public class OddSupport extends Support {
public OddSupport(String name) { // 构造函数
super(name);
}
protected boolean resolve(Trouble trouble) { // 解决问题的方法
if (trouble.getNumber() % 2 == 1) {
return true;
} else {
return false;
}
}
}
//只能解决编号为number的问题
public class SpecialSupport extends Support {
private int number;
public SpecialSupport(String name, int number) { // 构造函数
super(name);
this.number = number;
}
protected boolean resolve(Trouble trouble) { // 解决问题的方法
if (trouble.getNumber() == number) {
return true;
} else {
return false;
}
}
}
public class Main {
public static void main(String[] args) {
Support noSupportMan = new NoSupport("noSupportMan");
Support lt2Man = new LimitSupport("lt2Man", 2);
Support specialFor5Man =
new SpecialSupport("specialFor5Man", 5);
Support lt10Man = new LimitSupport("lt10Man", 10);
Support oddMan = new OddSupport("oddMan");
Support lt15Man = new LimitSupport("lt15Man", 15);
// 一层一层深入设置职责链条
noSupportMan
.setNext(lt2Man)
.setNext(specialFor5Man)
.setNext(lt10Man)
.setNext(oddMan)
.setNext(lt15Man);
// 解决各种问题
for (int i = 0; i < 17; i++) {
noSupportMan.support(new Trouble(i));
}
}
}
//结果
[Trouble 0] is resolved by [lt2Man].
[Trouble 1] is resolved by [lt2Man].
[Trouble 2] is resolved by [lt10Man].
[Trouble 3] is resolved by [lt10Man].
[Trouble 4] is resolved by [lt10Man].
[Trouble 5] is resolved by [specialFor5Man].
[Trouble 6] is resolved by [lt10Man].
[Trouble 7] is resolved by [lt10Man].
[Trouble 8] is resolved by [lt10Man].
[Trouble 9] is resolved by [lt10Man].
[Trouble 10] is resolved by [lt15Man].
[Trouble 11] is resolved by [oddMan].
[Trouble 12] is resolved by [lt15Man].
[Trouble 13] is resolved by [oddMan].
[Trouble 14] is resolved by [lt15Man].
[Trouble 15] is resolved by [oddMan].
[Trouble 16] cannot be resolved.
3. 模式的角色和类图
角色
- Handler(处理者):定义了处理请求的接口,这个角色知道下一个Handler是谁,如果自己处理不了就会交给下一个Handler处理。本例中,由Support类扮演此角色。
- ConcreteHandler(具体的处理者):实现了具体的处理方法。由NoSupport、LimitSupport、OddSupport、SpecialSupport扮演此角色。
- Client(请求者):向处理者发送问题请求的角色,本例中由Main类扮演此角色。
类图

4. 思路拓展
弱化了发出请求的人和处理请求的人的关系
可以动态改变职责链
专注于自己的工作
模式的缺点:责任被传递,请求会延迟
《图解设计模式》读书笔记6-2 Chain of Responsibility模式的更多相关文章
- 设计模式(十四)Chain of Responsibility模式
Chain of Responsibility模式就是当外部请求程序进行某个处理,但程序暂时无法直接决定由哪个对象负责处理时,就需要推卸责任.也就是说,当一个人被要求做什么事时,如果他可以做就自己做, ...
- CSharp设计模式读书笔记(24):访问者模式(学习难度:★★★★☆,使用频率:★☆☆☆☆)
模式角色与结构: 示例代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; ...
- CSharp设计模式读书笔记(23):模板方法模式(学习难度:★★☆☆☆,使用频率:★★★☆☆)
模板方法模式:定义一个操作中算法的框架,而将一些步骤延迟到子类中.模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 模式角色与结构: 实现代码: using System; ...
- CSharp设计模式读书笔记(22):策略模式(学习难度:★☆☆☆☆,使用频率:★★★★☆)
策略模式(Strategy Pattern):定义一系列算法类,将每一个算法封装起来,并让它们可以相互替换,策略模式让算法独立于使用它的客户而变化,也称为政策模式(Policy). 模式角色与结构: ...
- CSharp设计模式读书笔记(21):状态模式(学习难度:★★★☆☆,使用频率:★★★☆☆)
模式角色与结构: 示例代码:(本示例在具体状态类中实现状态切换,也可以在环境类中实现状态切换.状态模式一定程度上违背开闭原则) using System; using System.Collectio ...
- CSharp设计模式读书笔记(19):备忘录模式(学习难度:★★☆☆☆,使用频率:★★☆☆☆)
备忘录模式(Memento Pattern):在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态.它是一种对象行为型模式,其别名为Tok ...
- CSharp设计模式读书笔记(17):迭代器模式(学习难度:★★★☆☆,使用频率:★★★★★)
迭代器模式(Iterator Pattern):提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示,其别名为游标(Cursor). 模式角色与结构: 实现代码: using System; us ...
- CSharp设计模式读书笔记(15):命令模式(学习难度:★★★☆☆,使用频率:★★★★☆)
命令模式(Command Pattern):将一个请求封装为一个对象,从而让我们可用不同的请求对客户进行参数化:对请求排队或者记录请求日志,以及支持可撤销的操作.命令模式是一种对象行为型模式,其别名为 ...
- CSharp设计模式读书笔记(13):代理模式(学习难度:★★★☆☆,使用频率:★★★★☆)
代理模式:给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问. 模式角色与结构: 示例代码: using System; using System.Collections.Generi ...
- CSharp设计模式读书笔记(11):外观模式(学习难度:★☆☆☆☆,使用频率:★★★★★)
定义: 外观模式:为子系统中的一组接口提供一个统一的入口.外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 模式角色与结构: 示例代码: using System; using Sys ...
随机推荐
- [Linux] 014 帮助命令
1. 帮助命令:man 命令名称:man 命令所在路径:/bin/man 执行权限:所有用户 语法:man [命令或配置文件] 功能描述:获得帮助信息 范例: 查看 ls 命令的帮助信息 $ man ...
- 命令行打包war包
输入jar -cvf 包名.war 目录/*
- Codeforces 1097D (DP+分解质因数)
题目 传送门 分析 考虑\(n=p^q\)且p为质数的情况 设dp[i][j]表示经过i次变化后数为\(p^j\)的概率 则初始值dp[0][q]=1 状态转移方程为\(dp[i][j]=\sum{} ...
- P2737 [USACO4.1]麦香牛块Beef McNuggets
题目描述 农夫布朗的奶牛们正在进行斗争,因为它们听说麦当劳正在考虑引进一种新产品:麦香牛块.奶牛们正在想尽一切办法让这种可怕的设想泡汤.奶牛们进行斗争的策略之一是“劣质的包装”.“看,”奶牛们说,“如 ...
- Anaconda Jupyter WinError2:The system cannot find the file specified
Traceback (most recent call last): File "C:\Users\builder\Miniconda3\Scripts\conda-build-script ...
- 21、numpy—Matplotlib
NumPy Matplotlib Matplotlib 是 Python 的绘图库. 它可与 NumPy 一起使用,提供了一种有效的 MatLab 开源替代方案. 它也可以和图形工具包一起使用,如 P ...
- 【学习总结】cpu缓存
参考链接: cpu缓存java性能问题初探 高速缓存 在内存与cpu寄存器之间,还有一块区域叫做cpu高速缓存,即我们常常说的cache. cache分为L1.L2.L3三级缓存,速度递减,离cpu越 ...
- html5 带声音的导航
代码实例: <!DOCTYPE html PUBLIC "-//W3C//DTDXHTML 1.0 Transitional//EN""http://www.w3. ...
- 【python实例】统计字符串里大写字母,小写字母的个数和非字母的个数
""" 给定一个以下字符串:统计大写字母的个数,小写字母的个数,非字母的个数. str1 = "ajdkkKDKEK1343KFKiriromfkfKKRIOW ...
- CentOS6.8 安装/升级Python2.7.x,并安装最新setuptools、pip、fabric程序总结
最终靠谱的可借鉴文档: 1.python官网 2.http://lovesoo.org/python-fabric-yuan-cheng-zi-dong-bu-shu-jian-jie.html 3. ...