定义

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。

将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

UML

优点

  1. 将请求的发送者和接收者解耦
  2. 可以简化你的对象,因为它不需要知道链的结构
  3. 通过改变链内的成员或调动他们的次序,允许你动态地新增或删除责任

缺点

  1. 并不保证请求一定会被执行,如果没有任何对象处理它的话,它可能会落到链尾端之外
  2. 可能不容观察运行时的特征,有碍于除错。

应用场景

  1. 经常被使用在窗口系统中,处理鼠标和键盘之类的事件。
  2. 当算法牵涉到一种链型运算,而且不希望处理过程中有过多的循环和条件选择语句,并
  3. 且希望比较容易的扩充文法,可以采用职责链模式。
  4. 有多个对象处理请求,到底怎么处理在运行时确定。
  5. 希望在不明确指定接收者的情况下,向多个对象中的一个提交请求。
  6. 可处理一个请求的对象集合应该被动态指定。

示例

我们来实现一个场景,请求聚餐费用时,一般是把请求提交到项目经理处,项目经理可以处理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)的更多相关文章

  1. atitit.(设计模式1)--—职责链(chain of responsibility)最佳实践O7 转换日期

    atitit.设计模式(1)---职责链模式(chain of responsibility)最佳实践O7 日期转换 1. 需求:::日期转换 1 2. 能够选择的模式: 表格模式,责任链模式 1 3 ...

  2. 职责链(Chain of Responsibility)模式在航空货运中的运用实例

    设计模式这东西,基本上属于“看懂一瞬间,用会好几年”.只有实际开发中,当某一模式很好的满足了业务需求时,才会有真切的感觉.借用一句<闪电侠>中,绿箭侠教导闪电侠的台词:“不是你碰巧遇到了它 ...

  3. C++设计模式实现--职责链(Chain of Responsibility)模式

    一. 概述 职责链模式: 使多个对象都有机会处理请求.从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 二. 举个样例 员工要求加薪 ...

  4. 设计模式C++描述----05.职责链(Chain of Responsibility)模式

    一. 概述 职责链模式: 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 二. 举个例子 员工要求加薪 ...

  5. 设计模式(十三) 职责链(chain of responsibility)

    软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径.设计模式中运用了面向对象编程语言的重要特性:封装.继承.多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累.最 ...

  6. 设计模式---数据结构模式之职责链模式(Chain of Responsibility)

    一:概念 职责链模式(CoR,Chain of Responsibility)是行为模式之一,该模式构造一系列分别担当不同的职责的类的对象来共同完成一个任务,这些类的对象之间像链条一样紧密相连,所以被 ...

  7. js设计模式——6.模板方法模式与职责链模式

    js设计模式——6.模板方法模式与职责链模式 职责链模式

  8. 行为型模式(八) 职责链模式(Chain of Responsibility)

    一.动机(Motivate) 在软件构建过程中,一个请求可能被多个对象处理,但是每个请求在运行时只能有一个接受者,如果显示指定,将必不可少地带来请求发送者与接受者的紧耦合.如何使请求的发送者不需要指定 ...

  9. 设计模式24---设计模式之职责链模式(Chain of Responsibility)(行为型)

    1.职责链模式讲解 1.1职责链定义 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 1.2职责链模式 ...

  10. 状态模式、职责链模式——省去if-else的繁琐结构

    小时候写日记都是这么写的:上午七点起床,八点之前洗脸刷牙吃早饭,十二点之前好好上课,中午一点,吃午饭,下午两点到六点,上课,下课,找请假,明天妈妈要带我去姥姥家,九点之前,看动画片,九点钟,收拾去姥姥 ...

随机推荐

  1. 20160125.CCPP详解体系(0004天)

    程序片段(01):宽字符.c 内容概要:宽字符 #include <stdio.h> #include <stdlib.h> #include <Windows.h> ...

  2. 【英语】Bingo口语笔记(42) - Got系列

  3. 2015-10-14 晴 tcp/ip

    今天看完ping, traceroute, ip选路,动态选路协议,dup, igmp, tftp, bootp,tcp

  4. redo和undo的区别

    转摘:http://blog.163.com/jing_playboy/blog/static/757362222012520104521864/   redo--> undo-->dat ...

  5. 阻塞、非阻塞的概念和select函数的阻塞功能

    其它文档: http://www.cnitblog.com/zouzheng/archive/2010/11/25/71711.html (1)阻塞block     所谓阻塞方式block,顾名思义 ...

  6. (C#)RichTextBox控件

    RichTextBox(有格式文本)控件可实现TextBox控件的所有功能. ❶在RichTextBox控件中显示滚动条 RichTextBox可设置Multiline属性来控制是否显示滚动套,tru ...

  7. Android实例] android获取web服务器端session并验证登陆

    传统网页实现用户登陆一般采用session或cookie记录用户基本信息又或者两者结合起来使用.android也可以采用session实现用户登陆验证并记录用户登陆状态时的基本信息,session是在 ...

  8. HDU5806 NanoApe Loves Sequence Ⅱ (BestCoder Round #86 C)二分

    分析:大于等于m的变成1,否则变成0,预处理前缀和,枚举起点,找到第一个点前缀和大于m即可 找第一个点可以二分可以尺取 #include <cstdio> #include <cst ...

  9. mac配置appium进行自动化测试

    先去brew.sh这个网站,拷贝最新的下载安装命令,黏贴到终端里,回车,按提示下载安装. 安装完毕后,运行brewupdate 看看是否有更新,然后输入brew ios-webkit-debug-pr ...

  10. Windows上的的神技能,你知道几个?(Windows技巧大全,已更新)

    不用借助任何第三方软件,其实Windows也大有可为——比你目前了解得至少要多得多,强大技能快来get起来! 1.文件隐藏谁的电脑里没点小秘密?东藏西藏到最后自己都找不到了有木有?今天教大家个隐藏文件 ...