Chain of Responsibility模式就是当外部请求程序进行某个处理,但程序暂时无法直接决定由哪个对象负责处理时,就需要推卸责任。也就是说,当一个人被要求做什么事时,如果他可以做就自己做,如果不能做就转给下一个人,以此类推。

  下面是示例程序的类图。

  

  下面是示例程序代码。

 package bigjunoba.bjtu.handler;

 public class Trouble {

     private int number;

     public Trouble(int number) {
this.number = number;
} public int getNumber() {
return number;
} public String toString() {
return "[Trouble " + number + "]";
} }

  Trouble类是表示发生的问题的类,number作为问题编号,通过getNumber方法得到问题编号。

 package bigjunoba.bjtu.handler;

 public abstract class Support {

     private String name;
private Support next; public Support(String name) {
super();
this.name = name;
} public Support setNext(Support next) {
this.next = next;
return next;
} public final void support(Trouble trouble) {
if (resolve(trouble)) {
done(trouble);
} else if (next != null) {
next.support(trouble);
}else {
fail(trouble);
}
} public String toString() {
return "[" + name + "]";
} protected abstract boolean resolve(Trouble trouble); protected void done(Trouble trouble) {
System.out.println(trouble + " is resolved by " + this + "." );
} protected void fail(Trouble trouble) {
System.out.println(trouble + " cannot be resolved.");
} }

  Support类是用来解决问题的抽象类,它是职责链上的对象。next字段保存了要推卸给的对象,即Support类的实例,可以通过setNext方法设定该对象。resolve方法如果返回true,则表示问题已经被处理,如果返回false,则表示问题还没有被处理。support方法调用resolve方法,如果解决了问题,那么就调用done方法,如果否则将问题交给下一个对象,如果到最后一个对象仍然没有人处理,那么就调用fail方法。这里注意的是support方法调用抽象resolve方法,这属于Template Method模式。

 package bigjunoba.bjtu.concretehandler;

 import bigjunoba.bjtu.handler.Support;
import bigjunoba.bjtu.handler.Trouble; public class NoSupport extends Support{ public NoSupport(String name) {
super(name);
} @Override
protected boolean resolve(Trouble trouble) {
return false;
} }
 package bigjunoba.bjtu.concretehandler;

 import bigjunoba.bjtu.handler.Support;
import bigjunoba.bjtu.handler.Trouble; public class OddSupport extends Support { public OddSupport(String name) {
super(name);
} @Override
protected boolean resolve(Trouble trouble) {
if (trouble.getNumber() % 2 == 1) {
return true;
} else {
return false;
}
} }
package bigjunoba.bjtu.concretehandler;

import bigjunoba.bjtu.handler.Support;
import bigjunoba.bjtu.handler.Trouble; public class SpecilaSupport extends Support{ private int number; public SpecilaSupport(String name, int number) {
super(name);
this.number = number;
} @Override
protected boolean resolve(Trouble trouble) {
if (trouble.getNumber() == number) {
return true;
} else {
return false;
}
}
}
 package bigjunoba.bjtu.concretehandler;

 import bigjunoba.bjtu.handler.Support;
import bigjunoba.bjtu.handler.Trouble; public class LimitSupport extends Support{ private int limit; public LimitSupport(String name, int limit) {
super(name);
this.limit = limit;
} @Override
protected boolean resolve(Trouble trouble) {
if (trouble.getNumber() < limit) {
return true;
} else {
return false;
}
} }

  这四种类Support类的子类不难理解。NoSupport类永远不解决问题;LimitSupport类只解决编号小于limit值的问题;OddSupport类只解决奇数编号问题;SpecialSupport类只解决特定编号的问题。

 package bigjunoba.bjtu.test;

 import bigjunoba.bjtu.concretehandler.LimitSupport;
import bigjunoba.bjtu.concretehandler.NoSupport;
import bigjunoba.bjtu.concretehandler.OddSupport;
import bigjunoba.bjtu.concretehandler.SpecilaSupport;
import bigjunoba.bjtu.handler.Support;
import bigjunoba.bjtu.handler.Trouble; public class Main { public static void main(String[] args) {
Support lian1 = new NoSupport("LianOne");
Support lian2 = new LimitSupport("LianTwo", 100);
Support lian3 = new SpecilaSupport("LianThree", 429);
Support lian4 = new LimitSupport("LianFour", 200);
Support lian5 = new OddSupport("LianFive");
Support lian6 = new LimitSupport("LianSix", 300);
//形成职责链
lian1.setNext(lian2).setNext(lian3).setNext(lian4).setNext(lian5).setNext(lian6);
//制造各种问题
for (int i = 0; i < 500; i += 33) {
lian1.support(new Trouble(i));
}
} }

  Main类首先生成了6个解决问题的实例,虽然都是Support类型的,但实际上由于Support类是抽象类,因此这些实例分别是四个不同的子类的实例。然后形成了职责链,接着制造问题进行处理。

[Trouble 0] is resolved by [LianTwo].
[Trouble 33] is resolved by [LianTwo].
[Trouble 66] is resolved by [LianTwo].
[Trouble 99] is resolved by [LianTwo].
[Trouble 132] is resolved by [LianFour].
[Trouble 165] is resolved by [LianFour].
[Trouble 198] is resolved by [LianFour].
[Trouble 231] is resolved by [LianFive].
[Trouble 264] is resolved by [LianSix].
[Trouble 297] is resolved by [LianFive].
[Trouble 330] cannot be resolved.
[Trouble 363] is resolved by [LianFive].
[Trouble 396] cannot be resolved.
[Trouble 429] is resolved by [LianThree].
[Trouble 462] cannot be resolved.
[Trouble 495] is resolved by [LianFive].

  根据输出结果来举一个例子具体分析一下这个过程。假设问题编号是429,那么可以这样来分析,首先创建了一个Trouble实例,并且把问题编号number设置为429,然后这个429问题实例传递给support方法,并用lian1来调用这个方法。主要分析的是调用方法的过程:先调用NoSupport类的resolve方法,结果返回false,然后next字段保存的是lian2,不为空,因此要执行lian2的support方法...以此类推,最后发现lian1,2都解决不了,最后交给了3,3可以解决,程序结束。这里的思想是用到了递归。

  有一个时序图也可以用来帮助理解。

  下面是Chain of Responsibility模式的类图。

  这里对类图不做过多解释,通过示例程序对这一模式理解应该很到位。

设计模式(十四)Chain of Responsibility模式的更多相关文章

  1. 设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型)

      设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型) 1.概述 类中的面向对象编程封装应用逻辑.类,就是实例化的对象,每个单独的对象都有一个特定的身份和状态.单独的对象是一种组织代码的 ...

  2. Java设计模式(14)责任链模式(Chain of Responsibility模式)

    Chain of Responsibility定义:Chain of Responsibility(CoR) 是用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合, ...

  3. 设计模式19:Chain Of Responsibility 职责链模式(行为型模式)

    Chain Of Responsibility 职责链模式(行为型模式) 请求的发送者与接受者 某些对象请求的接受者可能有多种多样,变化无常…… 动机(Motivation) 在软件构建过程中,一个请 ...

  4. 《图解设计模式》读书笔记6-2 Chain of Responsibility模式

    目录 1. 简介 2. 示例程序 类图 代码 3. 模式的角色和类图 角色 类图 4. 思路拓展 1. 简介 Chain of Responsibility模式是责任链模式,模式的核心就是转移责任.就 ...

  5. java设计模式解析(11) Chain责任链模式

    设计模式系列文章 java设计模式解析(1) Observer观察者模式 java设计模式解析(2) Proxy代理模式 java设计模式解析(3) Factory工厂模式 java设计模式解析(4) ...

  6. Chain of Responsibility模式

    熟悉VC/MFC的都知道,VC是“基于消息,事件驱动”,消息在VC开发中起着举足轻重的作用.MFC提供了消息的处理的链式处理策略,处理消息的请求将沿着预定好的路径依次进行处理.消息的发送者并不知道该消 ...

  7. 设计模式(二十四)——职责链模式(SpringMVC源码分析)

    1 学校 OA 系统的采购审批项目:需求是 采购员采购教学器材 1) 如果金额 小于等于 5000,  由教学主任审批 (0<=x<=5000) 2) 如果金额 小于等于 10000,   ...

  8. 设计模式学习笔记(十四)责任链模式实现以及在Filter中的应用

    责任链模式(Chain Of Responsibility Design Pattern),也叫做职责链,是将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求.当有请求发生时,可将请求沿着这条 ...

  9. 职责链(Chain of Responsibility)模式在航空货运中的运用实例

    设计模式这东西,基本上属于“看懂一瞬间,用会好几年”.只有实际开发中,当某一模式很好的满足了业务需求时,才会有真切的感觉.借用一句<闪电侠>中,绿箭侠教导闪电侠的台词:“不是你碰巧遇到了它 ...

随机推荐

  1. SPSS学习笔记参数检验—单样本t检验

    单样本t检验 目的:利用来自总体的样本数据,推断该总体的均值是否与指定的检验值存在差异. 适用条件:样本来自的总体应服从或者近似服从正态分布. 注:当样本量n比较大时:由中心极限定理得知,即使原数据不 ...

  2. Python 编译器与解释器

    Python 编译器与解释器 Python的环境我们已经搭建好了,可以开始学习基础知识了.但是,在此之前,还要先说说编译器与解释器相关的内容. 如果这部分内容,让你觉得难以理解或不能完全明白,可以暂时 ...

  3. 还在用SVN的人,要不要学Git?

    还在用SVN的人,要不要学Git? 提出这个问题,是因为很多小伙伴还不会使用Git. 在Git之前,是SVN的天下. SVN诞生于2001年,由于较为先进的管理方式而迅速取代了CVS. 很多80后小伙 ...

  4. 深入探究js中的隐式变量声明

    前两天遇到的问题,经过很多网友的深刻讨论,终于有一个相对可以解释的通的逻辑了,然后我仔细研究了一下相关的点,顺带研究了一下js中的隐式变量. 以下文章中提到的隐式变量都是指没有用var,let,con ...

  5. httpd2.4

    更换网站主页目录 1.在httpd.conf文件中更改documentroot为新的路径,并为其相应的路径给与相应的权限. Documentroot "/www/http" < ...

  6. [ngclass]、[ngstyle]、管道

    [ngclass] 动态改变一个元素的class ts: public classcolor:boolean=false; public list:any = [{title:"新闻1&qu ...

  7. ng 图片的引用

    对于图片的引用有两种类型 本地 业务逻辑中(使用url) 本地中图片需要存放在静态资源夹assets中下新建的文件夹images文件夹中 eg:images文件夹中有一张01.png 的图片 显示本地 ...

  8. 解决MVC中Model上的特性在EF框架刷新时清空的问题

    MVC中关于前端数据的效验一般都是通过在Model中相关的类上打上特性来实现. 但是在我们数据库发生改变,EF框架需要刷新时会把我们在Model上的特性全部清除,这样的话,我们前端的验证就会失效. 因 ...

  9. 【TencentOS tiny】又有一个操作系统开源

    新闻 2019年9月18日,腾讯宣布将开源 自主研发的轻量级物联网实时操作系统TencentOS tiny.相比市场上其它系统,腾讯TencentOS tiny在资源占用.设备成本.功耗管理以及安全稳 ...

  10. .Net下MoongoDB的简单调用

    1.安装.Net 驱动:Install-Package MongoDB.Driver 2.数据插入 //新建Person测试类 public class Person { public long Id ...