一、定义

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

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

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

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

二、结构

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

  主要涉及两个角色:

  • 抽象处理者角色(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. 为并发而生的 ConcurrentHashMap(Java 8)

    HashMap 是我们日常最常见的一种容器,它以键值对的形式完成对数据的存储,但众所周知,它在高并发的情境下是不安全的.尤其是在 jdk 1.8 之前,rehash 的过程中采用头插法转移结点,高并发 ...

  2. YiShop_如何选择B2C商城开发商

    说到B2C商城开发,现在网上搜索能搜出来一大堆开发公司的信息出来.面对如果巨大的信息用户应该如果去评估和判断哪家更适合自己呢!其实开发B2C商城不仅体现在一家开发公司本身的具体实力,还体现在对每一个商 ...

  3. java8版本base64加密解密

    首先,先是加密,这里我使用了base64类 try { String asB64 = Base64.getEncoder().encodeToString("http://www.baidu ...

  4. python3 三级菜单-基础版

    # -*- coding:utf-8 -*- data = { "北京":{ "东城区":{ "安定门":["国子监", ...

  5. Cs Round#56 D Find Path Union

    题意:有一棵如下的完全二叉树,求所有给定结点到根节点的路径的并有多少条边. 一开始联想到线段树,发现结点的排布很像线段树的标号.于是模仿线段树敲了一下,交上去发现3个点MLE了... 无心优化,跑去看 ...

  6. Atcoder R84 D Small Multiple

    题意:给定一个正整数K,求K的倍数中,各位上的数字之和最小是多少? 思路非常巧妙,对于一个数,我们有定义两种改变方式: 1.加1,则数字之和+1(9的情况另行考虑) 2.乘10,数字之和不变 对于末位 ...

  7. 经验总结22--抓取HTML数据,HtmlAgilityPack(续)

    假设获取的数据是HTML的话.我们就须要第三方工具有辅助获取我们须要的数据. 我选用了HtmlAgilityPack这么个工具. 首先肯定去网上下载一个,然后引用到项目中.下载地址:http://ht ...

  8. Android使用XUtils框架上传照片(一张或多张)和文本,server接收照片和文字(无乱码)

    Android上传图片,这里我使用了如今比較流行的XUtils框架.该框架能够实现文件上传.文件下载.图片缓存等等,有待研究. 以下是Android端上传的代码: xUtils.jar下载 Strin ...

  9. 你为什么还坚持.NET

    C#换什么比较合适? 从TIOBE来看,Java.C++.C.Python都好,对了,还不能忘了JS. Sql Server换什么比较合适? MySql挺好,Oracle也不错,也还有不少选择. 都挺 ...

  10. 一、Spring Cloud介绍

    springcloud 介绍 研究了一段时间spring boot了准备向spirng cloud进发,公司架构和项目也全面拥抱了Spring Cloud.在使用了一段时间后发现Spring Clou ...