定义

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

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

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. mysql script for dynamic running sql script

    ),startTime datetime,endTime datetime) BEGIN set @s1 = concat('SELECT * FROM ', deviceName , ' where ...

  2. Windows Tftpd32 DHCP服务器 使用

    /********************************************************************* * Windows Tftpd32 DHCP服务器 使用 ...

  3. ecshop 首页调用指定类产品

    方法一.已测试成功 1.在/includes/lib_goods.php最底部增加以下代码 function index_get_cat_id_goods_best_list($cat_id = '' ...

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

  5. 剖析OkHttp缓存机制

    现在应用市场上的 App 无一不需要网络操作,这些应用的开发者大多数都选择结合使用 OkHttp 和 Retrofit 来完成网络操作.okHttp 最为人称道的一个特性就是它的缓存机制,而我将在本篇 ...

  6. 学好Javascript是有方法的

    先声明下噢,这篇文章不是自个儿写的,看着好,希望前端小孩们可以和我一起加油,大家都来借鉴借鉴吧- 首先要说明的是,咱现在不是高手,最多还是一个半桶水,算是入了JS的门. 谈不上经验,都是一些教训. 这 ...

  7. jQuery 实现Bootstrap Chart 图表

    很多时候我们制作报表的时候需要图表,如果你使用bootstrap开发你的网站,如果你需要使用图表,那么最简单的方法就是就是使用bootstrap 的chart.js来实现图表,下面介绍方法 1.引入c ...

  8. 构建 XCache 的基本步骤

    构建 XCache 的基本步骤 在开始之前,首先确保 PHP 正常安装并核实 phpize 是否位于 shell 的 PATH 下.同时,还需要一个 C 编译器,例如 GNU Compiler Col ...

  9. VBS学习:流程控制语句判断结构

    一.数值运算: 1) Dim a,b,c a=inputbox("a是:","输入半径") b=Inputbox("b是:","输 ...

  10. 淘宝API开发(三)

    自动登录到淘宝定时获取订单: C#控制台程序 第一步,获得淘宝真实登录地址.淘宝授权地址(https://oauth.taobao.com/authorize?response_type=token& ...