行为类模式(一):职责链(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的繁琐结构
小时候写日记都是这么写的:上午七点起床,八点之前洗脸刷牙吃早饭,十二点之前好好上课,中午一点,吃午饭,下午两点到六点,上课,下课,找请假,明天妈妈要带我去姥姥家,九点之前,看动画片,九点钟,收拾去姥姥 ...
随机推荐
- LeetCode Linked List Cycle II 单链表环2 (找循环起点)
题意:给一个单链表,若其有环,返回环的开始处指针,若无环返回NULL. 思路: (1)依然用两个指针的追赶来判断是否有环.在确定有环了之后,指针1跑的路程是指针2的一半,而且他们曾经跑过一段重叠的路( ...
- yii2.0 url 跳转
//转发 $this->render('page1',['id'=>3,'mark'=>2]); //显示page1页面 并传递 id mark 2个参数 //重定向 $thi ...
- 【转】Github轻松上手4-常用的git命令
转自:http://blog.sina.com.cn/s/blog_4b55f6860100zzih.html 附上一些git的常见命令: • git remote add origin git ...
- dos 实用命令收集
隐藏文件夹: H:\>attrib gho +h +s +r 解决win2012服务器上网慢:netsh int tcp set global ecn=disable
- kinect 录制彩色和深度视频
安装 KinectSDK-v1.8-Setup.exe OpenNI-Windows-x86-2.1.0.msi Qt工程 拷贝 Redist 下内容到 编译的exe所在目录 #include < ...
- Cocos2d-android (02) 添加一个精灵对象
什么是精灵: 1.精灵就是游戏当中的一个元素,通常用于代表画面当前中的一个事物,例如主人公,NPC和背景元素等: 2.一个精灵对象通常都与一张图片关联 3.精灵对象可以通过动作对象(CCAction) ...
- 安装linux操作系统--浪潮服务器
一直都是在虚拟机上进行安装linux操作系统,在服务器上安装的很少,也没有碰到过没找到驱动的情况,例如什么raid卡驱动,网卡驱动等异常情况的发生. 这次安装了两台服务器,浪潮的提供的服务器,硬盘是两 ...
- python在linux上的GUI无法弹出界面
在进行python写GUI程序的时候,使用Tkinter,发现无法执行程序,报错如下: X connection to localhost:10.0 broken(explicit kill or s ...
- 【LeetCode】111 - Minimum Depth of Binary Tree
Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shor ...
- 现代浏览器内置的可等效替代jQuery的功能
jQuery的体积在不断的增大.新功能要不断增加,这是必然结果.虽然从版本1.8.3开始的瘦身效果明显,但不可否认的是,对于移动手机端的网 页开发,它仍然是不可接受的.当然,jQuery不是铁板一块, ...