一、定义

  避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

  主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。

  何时使用:在处理消息的时候以过滤很多道。

  如何解决:拦截的类都实现统一接口。

二、结构

从责任链模式的定义可以发现,责任链模式涉及的对象只有处理者角色,但由于有多个处理者,它们具有共同的处理请求的方法,所以这里抽象出一个抽象处理者角色进行代码复用。这样分析下来,责任链模式的结构图也就不言而喻了,具体结构图如下所示。

  主要涉及两个角色:

  • 抽象处理者角色(Handler):定义出一个处理请求的接口。这个接口通常由接口或抽象类来实现。
  • 具体处理者角色(ConcreteHandler):具体处理者接受到请求后,可以选择将该请求处理掉,或者将请求传给下一个处理者。因此,每个具体处理者需要保存下一个处理者的引用,以便把请求传递下去。

三、适用场景

1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。

2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。

3、可动态指定一组对象处理请求。

四、优缺点

优点:

1、降低耦合度。它将请求的发送者和接收者解耦。

2、简化了对象。使得对象不需要知道链的结构。

3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。

4、增加新的请求处理类很方便。

缺点:

1、不能保证请求一定被接收。

2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。

3、可能不容易观察运行时的特征,有碍于除错。

五、实现

  以公司采购东西为例来实现责任链模式。公司规定,采购架构总价在1万之内,经理级别的人批准即可,总价大于1万小于2万5的则还需要副总进行批准,总价大于2万5小于10万的需要还需要总经理批准,而大于总价大于10万的则需要组织一个会议进行讨论。  

// 采购请求
public class PurchaseRequest
{
// 金额
public double Amount { get; set; }
// 产品名字
public string ProductName { get; set; }
public PurchaseRequest(double amount, string productName)
{
Amount = amount;
ProductName = productName;
}
} // 审批人,Handler
public abstract class Approver
{
public Approver NextApprover { get; set; }
public string Name { get; set; }
public Approver(string name)
{
this.Name = name;
}
public abstract void ProcessRequest(PurchaseRequest request);
} // ConcreteHandler
public class Manager : Approver
{
public Manager(string name)
: base(name)
{ } public override void ProcessRequest(PurchaseRequest request)
{
if (request.Amount < 10000.0)
{
Console.WriteLine("{0} 批准购买 {1}", Name, request.ProductName);
}
else if (NextApprover != null)
{
NextApprover.ProcessRequest(request);
}
}
} // ConcreteHandler,副总
public class VicePresident : Approver
{
public VicePresident(string name)
: base(name)
{
}
public override void ProcessRequest(PurchaseRequest request)
{
if (request.Amount < 25000.0)
{
Console.WriteLine("{0} 批准购买 {1}", Name, request.ProductName);
}
else if (NextApprover != null)
{
NextApprover.ProcessRequest(request);
}
}
} // ConcreteHandler,总经理
public class President : Approver
{
public President(string name)
: base(name)
{ }
public override void ProcessRequest(PurchaseRequest request)
{
if (request.Amount < 100000.0)
{
Console.WriteLine("{0} 批准购买 {1}", Name, request.ProductName);
}
else
{
Console.WriteLine("Request需要组织一个会议讨论");
}
}
} class Program
{
static void Main(string[] args)
{
PurchaseRequest requestTelphone = new PurchaseRequest(4000.0, "手机");
PurchaseRequest requestSoftware = new PurchaseRequest(10000.0, "空调");
PurchaseRequest requestComputers = new PurchaseRequest(40000.0, "笔记本电脑"); Approver manager = new Manager("经理");
Approver Vp = new VicePresident("副总");
Approver Pre = new President("总经理"); // 设置责任链
manager.NextApprover = Vp;
Vp.NextApprover = Pre; // 处理请求
manager.ProcessRequest(requestTelphone);
manager.ProcessRequest(requestSoftware);
manager.ProcessRequest(requestComputers);
Console.ReadLine();
}
}

结果

经理 批准购买 手机
副总 批准购买 空调
总经理 批准购买 笔记本电脑

参考:

http://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html

http://www.cnblogs.com/zhili/p/ChainOfResponsibity.html

欢迎阅读本系列文章:Head First设计模式之目录

Head First设计模式之责任链模式的更多相关文章

  1. 乐在其中设计模式(C#) - 责任链模式(Chain of Responsibility Pattern)

    原文:乐在其中设计模式(C#) - 责任链模式(Chain of Responsibility Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 责任链模式(Chain of R ...

  2. php设计模式之责任链模式

    php设计模式之责任链模式 实际问题 你的论坛有举报功能,版主能解决粗口方面的举报,警察能解决严重一点的黄赌毒方面的举报,更严重的反政府的举报就需要由国安局来完成. 职场中每个人都有直属的上级,如果到 ...

  3. python设计模式之责任链模式

    python设计模式之责任链模式 开发一个应用时,多数时候我们都能预先知道哪个方法能处理某个特定请求.然而,情况并非总是如此.例如,想想任意一种广播计算机网络,例如最早的以太网实现.在广播计算机网络中 ...

  4. 【GOF23设计模式】责任链模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_责任链模式.公文审批.供应链系统的采购审批.异常链.过滤器和拦截器调用过程 package com.test.chainO ...

  5. C#设计模式:责任链模式

    设计模式是面向对象编程的基础,是用于指导程序设计.在实际项目开发过程中,并不是一味将设计模式进行套用,也不是功能设计时大量引入设计模式.应该根据具体需求和要求应用适合的设计模式.设计模式是一个老话题了 ...

  6. 详解java设计模式之责任链模式

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt175 从击鼓传花谈起 击鼓传花是一种热闹而又紧张的饮酒游戏.在酒宴上宾客依次 ...

  7. 【Unity与23种设计模式】责任链模式(Chain of Responsibility)

    GoF中定义: "让一群对象都有机会来处理一项请求,以减少请求发送者与接收者之间的耦合度.将所有的接受对象串联起来,让请求沿着串接传递,直到有一个对象可以处理为止." 举个现实中的 ...

  8. Java进阶篇设计模式之八 ----- 责任链模式和命令模式

    前言 在上一篇中我们学习了结构型模式的享元模式和代理模式.本篇则来学习下行为型模式的两个模式, 责任链模式(Chain of Responsibility Pattern)和命令模式(Command ...

  9. 设计模式之责任链模式——Java语言描述

    责任链模式为请求创建了一个接受者对象的链.这种模式给予请求的类型,对请求的发送者和接受者进行解耦.这种类型的设计模式属于行为模式.在这种模式下,通常每个接收者都包含对另一个接收者的引用.如果一个对象不 ...

随机推荐

  1. js 数组去重复的方法

    数组去重复是js中常用的方法,归纳了四种如下: 1. for + indexOf  去重复 var arr = [3,5,5,4,1,1,2,3,7,2,5]; var target = []; fo ...

  2. 直接编译caffe出现的两个问题

    工控机的环境之前已经配置好ubuntu14.04+CUDA7.5+cuDNN v4,再加opencv3.1.要用ResNet做分类,需要重新编译一个caffe框架.下载BVLC/caffe,接着修改M ...

  3. 移动 云MAS 发短信 .net HTTP 请求

    本人开发移动云MAS .net Http 请求  代码如下 using Newtonsoft.Json.Linq; using System; using System.Collections.Gen ...

  4. EasyUI实现异步载入tree(整合Struts2)

    首先jsp页面有一ul用于展现Tree <ul id="mytree"></ul> 载入Tree <script type="text/ja ...

  5. 做ppt经常使用站点

    推荐一下做PPT经常使用的站点 一.字体 http://font.chinaz.com 二.ppt模板:演界网 三.图标 http://www.easyicon.net/

  6. python内置函数(四)

    python内部提供了非常多内建函数. 以下让我们从a-z開始学习python的内建函数 1.1 id(object) 返回对象的id(身份),返回的这个是一个整数(integer)是唯一的,在这个对 ...

  7. OR1200中指令Cache的结构

    下面内容摘自<步步惊芯--软核处理器内部设计分析>一书 12.3 ICache结构 OR1200中实现ICache的文件有or1200_ic_top.v.or1200_ic_fsm.v.o ...

  8. POJ3621 Sightseeing Cows(最优比率环)

    题目链接:id=3621">http://poj.org/problem?id=3621 在一个有向图中选一个环,使得环上的点权和除以边权和最大.求这个比值. 经典的分数规划问题,我认 ...

  9. 存储与索引------《Designing Data-Intensive Applications》读书笔记3

    在上一篇的笔记之中,我们讨论了数据模型和查询语言.在第三章之中我们来聊一聊不同的数据引擎内部是如何实现存储和检索的,以及不同设计之间的折中与妥协. 1.键值对数据库 键值对数据库是数据库形式之中最简单 ...

  10. Django的Models

    Django的数据库配置: 1    django默认支持sqlite,mysql, oracle,postgresql数据库 2.   在django的项目中会默认使用sqlite数据库,如果要使用 ...