Chain Of Responsibility 职责链模式(行为型模式)

请求的发送者与接受者

某些对象请求的接受者可能有多种多样,变化无常……

动机(Motivation)

在软件构建过程中,一个请求可能被多个对象处理,但是每个请求在运行时只能有一个接受者,如果显示指定,将必不可少地带来请求发送者与接受者的紧耦合。

如何使请求的发送者不需要指定具体的接受者?让请求的接受者自己在运行时决定来处理请求,从而使两者解耦。

意图(Intent)

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

示例代码

    public abstract class BaseHandler
{
public abstract void HandleRequest(Request request);
public abstract bool CanHandleRequest(Request request);
} public class AHandler : BaseHandler
{
public override void HandleRequest(Request request)
{
//...
} public override bool CanHandleRequest(Request request)
{
//...
}
} public class BHandler : BaseHandler
{
public override void HandleRequest(Request request)
{
//...
} public override bool CanHandleRequest(Request request)
{
//...
}
} public class CHandler : BaseHandler
{
public override void HandleRequest(Request request)
{
//...
} public override bool CanHandleRequest(Request request)
{
//...
}
} public class Request
{
//...
} public class Sender
{
public void Process()
{
Request request=new Request();
//...
List<BaseHandler> handlerList=new List<BaseHandler>();
handlerList.Add(new AHandler());
handlerList.Add(new BHandler());
handlerList.Add(new CHandler()); foreach (var handler in handlerList)
{
if (handler.CanHandleRequest(request))
{
handler.HandleRequest(request);
}
}
}
}

如果我们不希望Sender中有这么多的Handler的调用,可以通过指责链模式修改:

    public abstract class BaseHandler
{
public BaseHandler(BaseHandler next)
{
this.Next = next;
} public BaseHandler Next { get; set; } protected abstract bool CanHandleRequest(Request request); public virtual void HandleRequest(Request request)
{
if (this.Next != null)
{
this.Next.HandleRequest(request);
}
}
} public class AHandler : BaseHandler
{
public AHandler(BaseHandler next)
: base(next)
{
} public override void HandleRequest(Request request)
{
if (this.CanHandleRequest(request))
{
//...
}
else
{
base.HandleRequest(request);
}
} protected override bool CanHandleRequest(Request request)
{
//...
}
} public class BHandler : BaseHandler
{
public BHandler(BaseHandler next)
: base(next)
{
} public override void HandleRequest(Request request)
{
//...
} protected override bool CanHandleRequest(Request request)
{
//...
}
} public class CHandler : BaseHandler
{
public CHandler(BaseHandler next)
: base(next)
{
} public override void HandleRequest(Request request)
{
//...
} protected override bool CanHandleRequest(Request request)
{
//...
}
} public class Request
{
//...
} public class Sender
{
public void Process(BaseHandler handler)
{
Request request = new Request();
//...
handler.HandleRequest(request);
}
}

客户端调用:

        static void Main(string[] args)
{
Sender sender=new Sender(); BaseHandler handler1 = new AHandler(null);
BaseHandler handler2 = new BHandler(handler1);
BaseHandler handler3 = new CHandler(handler2); sender.Process(handler3); Console.ReadKey();
}

结构(Structure)

一个典型的对象结构可能如下图所示:

Handler——定义一个处理请求的接口。(可选)实现后继链。
ConcreteHandler——处理它所负责的请求。可访问它的后继者。如果可处理该请求,就处理之;否则将该请求转发给它的后继者。
Client——向链上的具体处理者(ConcreteHandler)对象提交请求。

Chain Of Responsibility 模式的几个要点

  • Chain Of Responsibility 模式的应用场合在于“一个请求可能有多个接受者,但是最后真正的接受者只有一个”,只有这时候请求发送者与接受者的耦合才有可能出现“变化脆弱”的症状,职责链的目的就是将两者解耦,从而更好地应对变化。
  • 应用了Chain Of Responsibility 模式后,对象的职责分派将更具灵活性。我们可以在运行时动态添加、修改请求的处理职责。
  • 如果请求传递到职责链的末尾仍得不到处理,应该有一个处理的缺省机制。这也是每一个接受对象的责任,而不是发出请求的对象的责任。
  • 这种链传递的方式效率较低。

转载请注明出处:

作者:JesseLZJ
出处:http://jesselzj.cnblogs.com

设计模式19:Chain Of Responsibility 职责链模式(行为型模式)的更多相关文章

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

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

  2. 设计模式学习笔记——Chain of Responsibility职责链模式

    重点在链.一条链,如果本节点处理不了,则传递给下一个节点处理. 关键是如何传给下一个节点? 主要是由本节点决定传给哪一个节点. public class Client { public static ...

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

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

  4. go语言设计模式之Chain Of Responsibility(责任链)

    ChainOfResponsibility.go package ChainOfResponsibility import ( "fmt" "io" " ...

  5. C#设计模式学习笔记:(20)职责链模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8109100.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第八个模式--职 ...

  6. 设计模式之第13章-职责链模式(Java实现)

    设计模式之第13章-职责链模式(Java实现) “请假都那么麻烦,至于么.”“咋的了?”“这不快过年了么,所以我想早两天回去,准备一下,买买东西什么的,然后去给项目经理请假,但是他说快过年了,所以这个 ...

  7. 基于.net 职责链来实现 插件模式

    插件式的例子 QQ电脑管家,有很多工具列表,点一下工具下载后就可以开始使用了 eclipse ,X Server 等等 插件式的好处 插件降低框架的复杂性,把扩展功能从框架中剥离出来 让第三方有机会来 ...

  8. .net 职责链来实现 插件模式

    .net 职责链来实现 插件模式 插件式的例子 QQ电脑管家,有很多工具列表,点一下工具下载后就可以开始使用了 eclipse ,X Server 等等 插件式的好处 插件降低框架的复杂性,把扩展功能 ...

  9. FactoryMethod工厂方法模式(创建型模式)

    1.工厂方法模式解决的问题 现在有一个抽象的游戏设施建造系统,负责构建一个现代风格和古典风格的房屋和道路. 前提:抽象变化较慢,实现变化较快(不稳定) 整个抽象的游戏设施建造系统相对变化较慢,本例中只 ...

随机推荐

  1. jdbc调用sparksql on yarn

    spark sql访问hive表 1.将hive-site.xml拷贝到spark目录下conf文件夹 2.(非必需)将mysql的jar包引入到spark的classpath,方式有如下两种: 方式 ...

  2. 【BZOJ】1260 [CQOI2007]涂色paint(区间dp)

    题目 传送门:QWQ 分析 区间dp, 详见代码 代码 /************************************************************** Problem: ...

  3. css引用方式

    网页中引用CSS样式 内联样式 行内样式表 外部样式表 链接式 导入式 内嵌方式 style标签 <!doctype html> <html> <head> < ...

  4. nginx 1.12 配置解析php

    server { listen 80; server_name foo.com; root /path; index index.html index.htm index.php; location ...

  5. cento7.3下玩转sphinx

    cento7.5下玩转sphinx 1 安装依赖文件 yum install postgresql-libs unixODBC 2 下载 wget http://sphinxsearch.com/fi ...

  6. 异步编程之Generator(2)——剖析特性

    异步编程系列教程: (翻译)异步编程之Promise(1)--初见魅力 异步编程之Promise(2):探究原理 异步编程之Promise(3):拓展进阶 异步编程之Generator(1)--领略魅 ...

  7. TBluetoothLEDevice.UpdateOnReconnect

    System.Bluetooth.TBluetoothLEDevice.UpdateOnReconnect Description Indicates whether the manager auto ...

  8. mfc对话框启动就直接隐藏在右下角显示托盘图标

    之前在网络上找了一份mfc对话框启动就直接隐藏窗体,在右下角显示托盘图标的demo 在win7下可以正常使用,但在win10上直接溢出,导致计算机跟注销似的崩溃现象. 后来找到原因是因为在OnInit ...

  9. atl控件发布打包<转>

    http://www.cnblogs.com/gengaixue/archive/2010/08/13/1799112.html ActiveX打包与发布 在VS2005或VS2008安装后发现路径* ...

  10. Tomcat ( 单机多 Tomcat 并存 )

    简介: Tomcat 扩展( 一台服务器运行多个 tomcat ) 一.安装 JDK .Tomcat shell > rpm -ivh jdk-8u25-linux-x64.rpm # 安装 j ...