意图

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

适用性

在以下条件下使用:

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

结构

实现

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

    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. 用JAVA实现插值查询的方法(算近似值,区间求法)

    插值查询:如果有这样一张表,有一列叫水位,有一列叫库容,比如下面的图. 我现在想做这么一件事情:对于这个测站而言,当我输入某一个水位或者库容的时候,想要查询到对应的水位或者库容呢? 而这个值不一定是存 ...

  2. 使用nodejs爬取拉勾苏州和上海的.NET职位信息

    最近开始找工作,本人苏州,面了几家都没有结果很是伤心.在拉勾上按照城市苏州关键字.NET来搜索一共才80来个职位,再用薪水一过滤,基本上没几个能投了.再加上最近苏州的房价蹭蹭的长,房贷压力也是非常大, ...

  3. The Practice of .NET Cross-Platforms

    0x01 Preface This post is mainly to share the technologies on my practice about the .NET Cross-Platf ...

  4. .NET设计模式(2):1.2 抽象工厂模式(Abstract Factory)

    概述 抽象工厂模式(Abstract Factory)是所有形态的工厂模式中最为抽象和最具一般性的一种形态.抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式.抽象工厂模式可以向客户端提供一个接口 ...

  5. Javascript贪食蛇小游戏

    试玩:http://hovertree.com/game/9/ 贪吃蛇是一种风靡全球的小游戏,就是一条小蛇,不停地在屏幕上游走,吃各个方向出现的蛋,越吃越长.只要蛇头碰到屏幕四周,或者碰到自己的身子, ...

  6. 浅谈SQL Server中的三种物理连接操作

    简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge J ...

  7. C++_系列自学课程_第_9_课_C语言风格字符串_《C++ Primer 第四版》

    前面说了写关于数组和指针的内容,这次在这里讨论一下字符串,讨论一下C语言风格的字符串. 在C语言里面我们利用字符数组来对字符串进行处理, 在C++里面我们前面说过一种类类型string可以对字符串进行 ...

  8. 【新技术】CentOS系统下docker的安装配置及使用详解

    1 docker简介    Docker 提供了一个可以运行你的应用程序的封套(envelope),或者说容器.它原本是dotCloud 启动的一个业余项目,并在前些时候开源了.它吸引了大量的关注和讨 ...

  9. java语言中除数为零问题

    在以下几个例子中,输出结果如何? float aa=0; System.out.println(aa/0); System.out.println(1/aa); System.out.println( ...

  10. jQuery siteslider 动画幻灯片

    在线实例 效果一 效果二 使用方法 <div class="container demo-1">             <div id="slider ...