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. Java复习——多线程与并发库

    开启一个线程 实现一个线程的方式有两种:继承Thread类.实现Runnable接口(也存在说三种的情况,第三种是使用线程并发库中的线程池创建一个线程).这两种方法都需要重写Run方法,具体的线程逻辑 ...

  2. microtip Tooltip工具提示样式

    最近开发项目,想增加滑动提示文字,类似img alt和i的title,但是效果都不是很理想,当然jq也有,但是用起来比较繁琐,使用不是特别方便 于是在github上看到了一个不错的库: https:/ ...

  3. 连接ES的Java项目报Too many open files错误

    启动后查询open files 数量 lsof -p TOMCAT_PID | grep wc -l 结果大概是一千多,但是短短数小时后就会涨到8k以上,所以使用网上很多朋友通过执行ulimit -n ...

  4. 19_java之List和Set

    01List接口的特点 A:List接口的特点: a:它是一个元素存取有序的集合. 例如,存元素的顺序是11.22.33.那么集合中,元素的存储就是按照11.22.33的顺序完成的). b:它是一 ...

  5. 06_java之类概述

    01引用数据类型_类 * A: 数据类型 * a: java中的数据类型分为:基本类型和引用类型 * B: 引用类型的分类 * a: Java为我们提供好的类,比如说:Scanner,Random等. ...

  6. springboot-shiro chapter01——创建springboot webmvc环境

    简介:本章提供了springboot简单例子,主要包含以下内容 1.pom.xml依赖资源 2.springboot配置 3.web应用spring mvc 环境: IDEA15+ JDK1.8+ M ...

  7. Delphi IOS MusicPlayer 锁屏运行学习

    [weak] FMusicPlayer: TMusicPlayer; [weak]修饰, 编译器在处理这个变量的时候不会调用该变量内容的__ObjAddRef和__ObjRelease., proce ...

  8. Subversion Self Signed Certificates

    When connecting to Subversion repositories using SSL connections the SVN client checks the server ce ...

  9. linux 下的mysql 连接报错

    报错: Fri Jul 28 16:28:52 CST 2017 WARN: Establishing SSL connection without server’s identity verific ...

  10. MySQL数据库篇之pymysql模块的使用

    主要内容: 一.pymysql模块的使用 二.pymysq模块增删改查 1️⃣  pymsql模块的使用 1.前言:之前我们都是通过MySQL自带的命令行客户端工具mysql来操作数据库, 那如何在p ...