设计模式(十四)Chain of Responsibility模式
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模式的更多相关文章
- 设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型)
设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型) 1.概述 类中的面向对象编程封装应用逻辑.类,就是实例化的对象,每个单独的对象都有一个特定的身份和状态.单独的对象是一种组织代码的 ...
- Java设计模式(14)责任链模式(Chain of Responsibility模式)
Chain of Responsibility定义:Chain of Responsibility(CoR) 是用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合, ...
- 设计模式19:Chain Of Responsibility 职责链模式(行为型模式)
Chain Of Responsibility 职责链模式(行为型模式) 请求的发送者与接受者 某些对象请求的接受者可能有多种多样,变化无常…… 动机(Motivation) 在软件构建过程中,一个请 ...
- 《图解设计模式》读书笔记6-2 Chain of Responsibility模式
目录 1. 简介 2. 示例程序 类图 代码 3. 模式的角色和类图 角色 类图 4. 思路拓展 1. 简介 Chain of Responsibility模式是责任链模式,模式的核心就是转移责任.就 ...
- java设计模式解析(11) Chain责任链模式
设计模式系列文章 java设计模式解析(1) Observer观察者模式 java设计模式解析(2) Proxy代理模式 java设计模式解析(3) Factory工厂模式 java设计模式解析(4) ...
- Chain of Responsibility模式
熟悉VC/MFC的都知道,VC是“基于消息,事件驱动”,消息在VC开发中起着举足轻重的作用.MFC提供了消息的处理的链式处理策略,处理消息的请求将沿着预定好的路径依次进行处理.消息的发送者并不知道该消 ...
- 设计模式(二十四)——职责链模式(SpringMVC源码分析)
1 学校 OA 系统的采购审批项目:需求是 采购员采购教学器材 1) 如果金额 小于等于 5000, 由教学主任审批 (0<=x<=5000) 2) 如果金额 小于等于 10000, ...
- 设计模式学习笔记(十四)责任链模式实现以及在Filter中的应用
责任链模式(Chain Of Responsibility Design Pattern),也叫做职责链,是将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求.当有请求发生时,可将请求沿着这条 ...
- 职责链(Chain of Responsibility)模式在航空货运中的运用实例
设计模式这东西,基本上属于“看懂一瞬间,用会好几年”.只有实际开发中,当某一模式很好的满足了业务需求时,才会有真切的感觉.借用一句<闪电侠>中,绿箭侠教导闪电侠的台词:“不是你碰巧遇到了它 ...
随机推荐
- SpringCloud搭建注册中心与服务注册
上一篇文章<微服务注册中心原理,看这篇就够了!>介绍了注册中心的概念和原理,本文将介绍下利用Eureka搭建中心并注册服务到注册中心的过程. 本文目录 一.Eureka介绍二.搭建注册中心 ...
- <机器学习>无监督学习算法总结
本文仅对常见的无监督学习算法进行了简单讲述,其他的如自动编码器,受限玻尔兹曼机用于无监督学习,神经网络用于无监督学习等未包括.同时虽然整体上分为了聚类和降维两大类,但实际上这两类并非完全正交,很多地方 ...
- jq中attr()和prop() 属性的区别
query1.6中新加了一个方法prop(),一直没用过它,官方解释只有一句话:获取在匹配的元素集中的第一个元素的属性值. 大家都知道有的浏览器只要写disabled,checked就可以了,而有的要 ...
- $(document).height 与$(window).height的区别
$(document).scrollTop() 获取垂直滚动的距离 (即当前滚动的地方的窗口顶端到整个页面顶端的距离)$(document).scrollLeft() 这是获取水平滚动条的距离 要获取 ...
- Android NDK(一) ndk-build构建工具进行NDK开发
本文目录 一.androidstudio环境 二.快捷键配置 三.新建项目 四.NDK开发 五.so文件编译 一. androidstudio的环境 在SDK Tools中安装NDK开发环境(File ...
- Java匹马行天下之教你用学汉语式方法学编程语言
Java匹马行天下之教你用学汉语式方法学编程语言 前言: 前段时间接连更新了带小白从入门到了解的几篇博客: <Java匹马行天下之编程常识知多少> <Java匹马行天下之走进编程的殿 ...
- 控制器向视图传参ModelAndView、Model和Map
ModelAndView类 ModelAndView在spring-webmvc-4.3.18.RELEASE.jar包下,当然其他版本也有,所在包如下 对于那些返回String等类型的处理方法,sp ...
- python编程基础之十三
列表的通用操作: list1 = [43, 65, 76, 6] list2 = [45, 77, 90, 11, 2, 4, 66] print(list1+ list2) # 列表组合 prin ...
- LRU算法实现,HashMap与LinkedHashMap源码的部分总结
关于HashMap与LinkedHashMap源码的一些总结 JDK1.8之后的HashMap底层结构中,在数组(Node<K,V> table)长度大于64的时候且链表(依然是Node) ...
- asp.net core 使用 AccessControlHelper 控制访问权限
asp.net core 使用 AccessControlHelper 控制访问权限 Intro 由于项目需要,需要在基于 asp.net mvc 的 Web 项目框架中做权限的控制,于是才有了这个权 ...