行为类模式(一):职责链(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的繁琐结构
小时候写日记都是这么写的:上午七点起床,八点之前洗脸刷牙吃早饭,十二点之前好好上课,中午一点,吃午饭,下午两点到六点,上课,下课,找请假,明天妈妈要带我去姥姥家,九点之前,看动画片,九点钟,收拾去姥姥 ...
随机推荐
- UVALive 5532 King(差分约束,spfa)
题意:假设一个序列S有n个元素,现在有一堆约束,限制在某些连续子序列之和上,分别有符号>和<.问序列S是否存在?(看题意都看了半小时了!) 注意所给的形式是(a,b,c,d),表示:区间之 ...
- (转)Mac OS X写了个rm时将文件放入回收站的小工具
上次由于公司里机器要面临重装,开始仓皇地将Mac本里的文件scp到我的台式机上.忙乱之中本来要删除一个无用的文件夹的,结果用rm -rf的时候tab了一下,补全出来的文件都没看清就按下了回车,毫无疑问 ...
- 【英语】Bingo口语笔记(79) - fish系列
- list() and tuple()
>>> l = list('sdfsdf') >>> l ['s', 'd', 'f', 's', 'd', 'f'] >>> t = tuple ...
- 剑指offer-第二章算法之斐波拉契数列(青蛙跳台阶)
递归与循环 递归:在一个函数的内部调用这个函数. 本质:把一个问题分解为两个,或者多个小问题(多个小问题相互重叠的部分,会存在重复的计算) 优点:简洁,易于实现. 缺点:时间和空间消耗严重,如果递归调 ...
- Swift语法
Swift语法 标签(空格分隔): Swift 1.打印输出语句 println("Hello, Swift!") 注意每行代码后面无需添加分号作为结束 2.简单值 let---常 ...
- 基于CentOS与VmwareStation10搭建Oracle11G RAC 64集群环境:2.搭建环境-2.7. 配置资源与参数
2.7.配置资源与参数 2.7.1. 修改主机名称 [root@linuxrac1 ~]# cd /etc/sysconfig [root@linuxrac1 sysconfig]# vi netwo ...
- android webview 遇到的问题:external/chromium/net/disk_cache/stat_hub.cc:216:
今天也遇到这个问题,界面显示无法访问,Baidu吧,结果有些含糊其词,有的说加网络权限,我看了下我的, 有个 <uses-permission android:name="androi ...
- JDBC用ResultSet访问大量数据时会遇到的问题
我们经常需要JDBC来对数据库就行操作,一般流程为连接数据库.通过sql语句把需要的数据取出来保存到ResultSet,然后调用ResultSet方法的类似 getString,getInt()等方法 ...
- (C#)RichTextBox控件
RichTextBox(有格式文本)控件可实现TextBox控件的所有功能. ❶在RichTextBox控件中显示滚动条 RichTextBox可设置Multiline属性来控制是否显示滚动套,tru ...