行为类模式(一):职责链(Chain Of Responsibility)
定义
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
UML
优点
- 将请求的发送者和接收者解耦
- 可以简化你的对象,因为它不需要知道链的结构
- 通过改变链内的成员或调动他们的次序,允许你动态地新增或删除责任
缺点
- 并不保证请求一定会被执行,如果没有任何对象处理它的话,它可能会落到链尾端之外
- 可能不容观察运行时的特征,有碍于除错。
应用场景
- 经常被使用在窗口系统中,处理鼠标和键盘之类的事件。
- 当算法牵涉到一种链型运算,而且不希望处理过程中有过多的循环和条件选择语句,并
- 且希望比较容易的扩充文法,可以采用职责链模式。
- 有多个对象处理请求,到底怎么处理在运行时确定。
- 希望在不明确指定接收者的情况下,向多个对象中的一个提交请求。
- 可处理一个请求的对象集合应该被动态指定。
示例
我们来实现一个场景,请求聚餐费用时,一般是把请求提交到项目经理处,项目经理可以处理500元以下的费用,如果费用高于500元就需要部门经理审批,如果高于1000元则需要总经理审批。
而可能出现的新需求是:公司改变了规则,高于1000元的部分要先由财务审批后再交给总经理,或者是去掉了部门经理审批的环节。通过责任链就可以方便的动态修改。
Java
public class Main
{
public static void main(String[] args)
{
Handler h1 = new ProjectManager();
Handler h2 = new DepManager();
Handler h3 = new GeneralManager();
h1.setSuccessor(h2);
h2.setSuccessor(h3); System.out.println(h1.handlerFeeRequest("小李", 300));
System.out.println(h1.handlerFeeRequest("小张", 300)); System.out.println(h1.handlerFeeRequest("小李", 800));
System.out.println(h1.handlerFeeRequest("小张", 800)); System.out.println(h1.handlerFeeRequest("小李", 3000));
System.out.println(h1.handlerFeeRequest("小张", 3000));
} /**
* 责任处理对象
*/
public static abstract class Handler
{
/**
* 下一个处理请求的处理对象
*/
protected Handler successor; /**
* 设置下一个处理对象
*/
public void setSuccessor(Handler successor)
{
this.successor = successor;
} /**
* 处理聚餐费用的请求
*/
public abstract String handlerFeeRequest(String name, double fee);
} public static class ProjectManager extends Handler
{
@Override
public String handlerFeeRequest(String name, double fee)
{
String str = "";
if(fee < 500)
{
//小于500元的可以处理
if("小李".equals(name))
{
str = "项目经理同意" + name + "的聚餐费用" + fee + "元的请求";
}
else
{
str = "项目经理不同意" + name + "的聚餐费用" + fee + "元的请求";
}
}
else
{
if(this.successor != null)
{
return this.successor.handlerFeeRequest(name, fee);
}
}
return str;
}
} public static class DepManager extends Handler
{
@Override
public String handlerFeeRequest(String name, double fee)
{
String str = "";
if(fee < 1000)
{
//小于1000元的可以处理
if("小李".equals(name))
{
str = "部门经理同意" + name + "的聚餐费用" + fee + "元的请求";
}
else
{
str = "部门经理不同意" + name + "的聚餐费用" + fee + "元的请求";
}
}
else
{
if(this.successor != null)
{
return this.successor.handlerFeeRequest(name, fee);
}
}
return str;
}
} public static class GeneralManager extends Handler
{
@Override
public String handlerFeeRequest(String name, double fee)
{
String str = "";
//可以处理任意金额
if("小李".equals(name))
{
str = "总经理同意" + name + "的聚餐费用" + fee + "元的请求";
}
else
{
str = "总经理不同意" + name + "的聚餐费用" + fee + "元的请求";
}
return str;
}
}
}
行为类模式(一):职责链(Chain Of Responsibility)的更多相关文章
- atitit.(设计模式1)--—职责链(chain of responsibility)最佳实践O7 转换日期
atitit.设计模式(1)---职责链模式(chain of responsibility)最佳实践O7 日期转换 1. 需求:::日期转换 1 2. 能够选择的模式: 表格模式,责任链模式 1 3 ...
- 职责链(Chain of Responsibility)模式在航空货运中的运用实例
设计模式这东西,基本上属于“看懂一瞬间,用会好几年”.只有实际开发中,当某一模式很好的满足了业务需求时,才会有真切的感觉.借用一句<闪电侠>中,绿箭侠教导闪电侠的台词:“不是你碰巧遇到了它 ...
- C++设计模式实现--职责链(Chain of Responsibility)模式
一. 概述 职责链模式: 使多个对象都有机会处理请求.从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 二. 举个样例 员工要求加薪 ...
- 设计模式C++描述----05.职责链(Chain of Responsibility)模式
一. 概述 职责链模式: 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 二. 举个例子 员工要求加薪 ...
- 设计模式(十三) 职责链(chain of responsibility)
软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径.设计模式中运用了面向对象编程语言的重要特性:封装.继承.多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累.最 ...
- 设计模式---数据结构模式之职责链模式(Chain of Responsibility)
一:概念 职责链模式(CoR,Chain of Responsibility)是行为模式之一,该模式构造一系列分别担当不同的职责的类的对象来共同完成一个任务,这些类的对象之间像链条一样紧密相连,所以被 ...
- js设计模式——6.模板方法模式与职责链模式
js设计模式——6.模板方法模式与职责链模式 职责链模式
- 行为型模式(八) 职责链模式(Chain of Responsibility)
一.动机(Motivate) 在软件构建过程中,一个请求可能被多个对象处理,但是每个请求在运行时只能有一个接受者,如果显示指定,将必不可少地带来请求发送者与接受者的紧耦合.如何使请求的发送者不需要指定 ...
- 设计模式24---设计模式之职责链模式(Chain of Responsibility)(行为型)
1.职责链模式讲解 1.1职责链定义 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 1.2职责链模式 ...
- 状态模式、职责链模式——省去if-else的繁琐结构
小时候写日记都是这么写的:上午七点起床,八点之前洗脸刷牙吃早饭,十二点之前好好上课,中午一点,吃午饭,下午两点到六点,上课,下课,找请假,明天妈妈要带我去姥姥家,九点之前,看动画片,九点钟,收拾去姥姥 ...
随机推荐
- selinux --chcon命令
chcon命令:修改对象(文件)的安全上下文.比如:用户:角色:类型:安全级别. 命令格式: Chcon [OPTIONS…] CONTEXT FILES….. Chcon [OPTIONS…] –r ...
- linux vim 配置文件(高亮+自动缩进+行号+折叠+优化)
点评:将一下代码copy到 用户目录下 新建文件为 .vimrc保存即可生效 如果想所有用户生效 请修改 /etc/vimrc (建议先cp一份)"===================== ...
- matlab中矩阵和向量的创建
1.向量的创建 1)直接输入: 行向量:a=[1,2,3,4,5] 列向量:a=[1;2;3;4;5] 2)用“:”生成向量 a=J:K 生成的行向量是a=[J,J+1,…,K] a=J:D:K 生成 ...
- erl0009 - erlang 读取时间瓶颈解决办法
读取时间erlang提供有两种方式: 1.erlang:now(); 2.os:timestamp(); 以上两种方式由于erlang系统需要保证读取精度,当并发读取的时候会引起加锁.系统频繁读取时间 ...
- JS面向对象组件(六) -- 拖拽功能以及组件的延展
HTML部分 <div id="div1"></div> <div id="div2"></div> CSS部分 ...
- centos下安装python
下载网址:http://ftp.gnu.org/gnu/gdb/ 1.编译python必须安装开发工具 # yum groupinstall "Development tools" ...
- 【Linux】一个简单的线程创建和同步的例子
最近很多精力在Linux上,今天简单看了一下Linux上的线程和同步,其实不管windows还是Linux,OS层面的很多原理和概念都是相同的,很多windows之上的经验和概念完全可以移植到Linu ...
- 在刚接触TI-DM8127-ipnc框架时注意的问题
1. 修改内存分配不成功? 解决方法: 修改内存分配后需要重新编译mcfw.它影响3个核. 如果修改了cmem需要修改boostara. 2. 命令make clean后在make相机跑不起来? 解决 ...
- 安装 nodejs图像处理模块 sharp
sudo npm install sharp 报错: ERROR: Please install libvips by running: brew install homebrew/science/v ...
- 如何通过Android Studio发布library到jCenter和Maven Central
http://www.jianshu.com/p/3c63ae866e52# 在Android Studio里,如果你想引入任何library到自己的项目中,只需要很简单的在module的build. ...