意图

使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

适用性

在以下条件下使用:

  • 有多个对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
  • 你想在不明确指定接受者的情况下,向多个对象中的一个提交一个请求。
  • 可处理一个请求的对象集合应该被动态指定。

结构

实现

实现一个邮件处理系统,将邮件按照类别交给不同的对象处理。
已经分类的邮件

    public class Request
{
public Request(string type)
{
Type = type;
}
private string _content;
public string Type { get; set; }
}

处理的抽象,类似链表,自身包含指向下一个处理节点的对象

    public abstract class Handler
{
protected Handler _nextHandler;
public abstract void ProcessRequest(Request request);
public void SetNext(Handler handler)
{
_nextHandler = handler;
}
}

对不同类型进行处理的对象

    //粉丝邮件处理
public class FanHandler:Handler
{
public override void ProcessRequest(Request request)
{
if (request.Type=="fan")
{
Console.WriteLine("fan's email process");
}
else
{
_nextHandler.ProcessRequest(request);
}
}
}
//垃圾邮件处理
public class SpamHandler : Handler
{
public override void ProcessRequest(Request request)
{
if (request.Type == "spam")
{
Console.WriteLine("spam delete");
}
else
{
_nextHandler.ProcessRequest(request);
}
}
}
//抱怨和意见邮件处理
public class ComplaintHandler:Handler
{
public override void ProcessRequest(Request request)
{
if (request.Type=="complaint")
{
Console.WriteLine("complaint process");
}
else
{
_nextHandler.ProcessRequest(request);
}
}
}
//其他邮件处理
public class DefaultHandler:Handler
{
public override void ProcessRequest(Request request)
{
Console.WriteLine("Do some thing!");
}
}

使用之前,先要将责任链串联起来

 class Program
{
static void Main(string[] args)
{
//发送者
var fan = new Request("fan");
var spam = new Request("spam");
var complaint = new Request("complaint");
var other = new Request("other");
//接受者
var fanHandler = new FanHandler();
var spamHandler = new SpamHandler();
var complaintHandler = new ComplaintHandler();
var defaultHandler = new DefaultHandler(); //构造责任链
fanHandler.SetNext(spamHandler);
spamHandler.SetNext(complaintHandler);
complaintHandler.SetNext(defaultHandler); //请求交由责任链头节点处理
fanHandler.ProcessRequest(fan);
fanHandler.ProcessRequest(spam);
fanHandler.ProcessRequest(complaint);
fanHandler.ProcessRequest(other);
Console.ReadKey(); }
}

运行结果

效果

  1. 降低耦合度
  2. 增强了给对象指派职责的灵活性
  3. 不保证被接受(用一个默认处理类来解决这个问题)

参考

  1. 《Head First 设计模式》
  2. 《设计模式》
  3. C#设计模式(21)——责任链模式

设计模式C#实现(十四)——责任链模式的更多相关文章

  1. 设计模式之二十:责任链模式(Chain of Responsibility)

    感觉这个设计模式和组合模式一样是一种非常巧妙的设计模式,在须要使用它的地方假设不使用这样的设计模式代码会变的非常复杂,可是这样的设计模式的基本原理又是非常easy的. 责任链模式: 通过使多个对象都有 ...

  2. Java 设计模式系列(十四)命令模式(Command)

    Java 设计模式系列(十四)命令模式(Command) 命令模式把一个请求或者操作封装到一个对象中.命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复 ...

  3. Java设计模式十九——责任链模式

    责任链模式 老李的苦恼 每个人在出生的时候,都早已在暗中被标好了三六九等. 老李是一名建筑工地的木匠,和大多数生活在社会最底层的农民工一样,一辈子老实本分,胆小怕事.在他们的心中,谁当老爷都没有区别, ...

  4. java23种设计模式之十:责任链模式

    最近在学习netty中发现其中用到了责任链模式,然后结合自己在写代码中遇到了大量写if...else的情况,决定学习一下责任链模式. 一.什么样的场景下会选择用责任链模式 我们在进行业务逻辑判断时,需 ...

  5. 设计模式(C#)——12责任链模式

    推荐阅读:  我的CSDN  我的博客园  QQ群:704621321 前言        在开发游戏过程中,当玩家合成一种道具的时候,对于不痛的道具,需要的碎片个数,类型是不同的.用传统的写法,就是 ...

  6. python 设计模式之 (Chain of Responsibility)责任链模式

    #写在前面 对于每一种设计模式,如果不理解它的原理和结构,是写不出例子来的.所以弄明白很重要. 等过完这段浑浑噩噩的日子,我要找个遍地开花的地方开怀大笑一场 #责任链模式定义 简书上一网友就把这个定义 ...

  7. iOS设计模式解析(五)责任链模式

    责任链模式:使多个对象都有机会处理请求,从而避免发送者和接受者之间发生耦合. 应用场景: 有多个对象可以处理请求,而处理程序只有在运行时才能确定 例如: 英雄联盟中伤害计算,伤害类型分为AP.AD.真 ...

  8. 设计模式(13)--Chain of Responsibility(责任链模式)--行为型

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一 ...

  9. 【设计模式】行为型05责任链模式(Chain of responsibility Pattern)

    学习地址:http://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html demo采用了DEBUG级别举例子,理解起 ...

  10. java设计模式8.迭代子模式、责任链模式、命令模式

    迭代子模式 迭代子模式可以顺序地访问一个聚集中的元素而不必暴露聚集的内部表象.它将迭代逻辑封装到一个独立的迭代子对象中,从而与聚集本身分开.迭代子对象是对遍历的抽象化,不同的聚集对象可以提供相同的迭代 ...

随机推荐

  1. Mybatis - 动态sql

    learn from:http://www.mybatis.org/mybatis-3/dynamic-sql.html mybatis支持动态拼接sql语句.主要有: if choose (when ...

  2. TCP的定时器

    TCP的定时器 在TCP协议中有的时候需要定期或者按照某个算法对某个事件进行触发,那么这个时候,TCP协议是使用定时器进行实现的.在TCP中,会有四种定时器: 重传定时器 坚持定时器 保活定时器 2M ...

  3. 前端读取Excel报表文件

    在实际开发中,经常会遇到导入Excel文件的需求,有的产品人想法更多,想要在前端直接判断文件内容格式是否正确,必填项是否已填写 依据HTML5的FileReader,可以使用新的API打开本地文件(参 ...

  4. 十大经典排序算法总结(JavaScript描述)

    前言 读者自行尝试可以想看源码戳这,博主在github建了个库,读者可以Clone下来本地尝试.此博文配合源码体验更棒哦~~~ 个人博客:Damonare的个人博客 原文地址:十大经典算法总结 这世界 ...

  5. div+css页面右侧底部悬浮层

    效果体验:http://hovertree.com/texiao/css/23/ 效果图: 代码如下: <!DOCTYPE html> <html> <head> ...

  6. .Net中的并行编程-3.ConcurrentQueue实现与分析

    在上文<.Net中的并行编程-2.ConcurrentQueue的实现与分析> 中解释了无锁的相关概念,无独有偶BCL提供的ConcurrentQueue也是基于原子操作实现, 由于Con ...

  7. windows对象模型分类

  8. C标准头文件<signal.h>

    信号即异常,或者理解为中断,一个进程接收到一个信号,如果没有处理机制,就会按照默认的处理方式进行处理,而默认的处理方式通常是终止当前进程或忽略该信号.当然,程序也可以编写相应的处理信号的函数,一旦接收 ...

  9. C语言: 预处理

    1. 字符映射 键盘有多种标准规格,例如常用的IBM 104键盘标准,然而不是所有键盘都能打出像#这样的符号,因此C语言的预处理引入了字符映射机制.如果程序员要求,预处理会按照约定对源代码中的字符进行 ...

  10. [moka同学转载]Yii2 checkBookList的使用

    use yii\helpers\Html; use yii\helpers\ArrayHelper model层代码 $model = new Model()//要存储的model $aclb = A ...