设计模式(十四)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)模式在航空货运中的运用实例
设计模式这东西,基本上属于“看懂一瞬间,用会好几年”.只有实际开发中,当某一模式很好的满足了业务需求时,才会有真切的感觉.借用一句<闪电侠>中,绿箭侠教导闪电侠的台词:“不是你碰巧遇到了它 ...
随机推荐
- [python]汉诺塔问题
相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏.该游戏是在一块铜板装置上,有三根杆(编号A.B.C),在A杆自下而上.由大到小按顺序放置64个金盘(如下图).游戏的目标:把A杆上的金盘全部 ...
- 程序员写 2000 行 if else?领导:这个锅我不背
前言 知乎上有小伙伴提了这么一个问题,如何看待陕西省普通话水平测试成绩查询系统?查询系统前端代码就直接给出了身份账号,姓名,证书编号,如果信息是真的,就泄露了这么多考生的信息,白给那种.为什么会发生这 ...
- Spring 梳理 - AOP那些学术概念—通知、增强处理连接点(JoinPoint)切面(Aspect)
Spring AOP那些学术概念—通知.增强处理连接点(JoinPoint)切面(Aspect) 1.我所知道的AOP 初看起来,上来就是一大堆的术语,而且还有个拉风的名字,面向切面编程,都说是 ...
- js常用Matn函数的操练
Math.PI console.log(Math.PI); 随机数以及向下取整 这是一个能实现从a-b之间随机打印一个整数 function rand_s(a, b) { var x = a + (b ...
- 多线程下的wait为什么可以不需要notify
多线程下的wait方法就像我无处安放的青春,胡乱来,感觉没有一点套路.wait后不需要notify仍可以继续执行.所以我决定看看到底咋回事..... 先结合join方法了解一下. join方法是可以等 ...
- IMongoQuery的使用-C#
一.Mongodb的IMongoQuery的使用 引用命名空间:MongoDB.Driver;MongoDB.Driver.Builders; Query.All("name", ...
- bugku旋转跳跃
下载下是一个mp3音频,尝试听了下,没有收获, 使用mp3stege,将文件拷在mp3stege目录下,然后使用cmd cd到目录下 命令行是decode -X -P 密码 文件 生成了一个文本 打开 ...
- SQL 存储过程示例讲解
create proc score_result ) --参数 as declare --定义变量@courseNo int, @testTime1 datetime, @avg int begin ...
- MySQL优化与实践
一.MySQL优化概括 二.SQL优化 实践: 1.查看是否开启了慢查询日志 show variables like 'slow_query_log' 没有开启 2.查看是否开启了未使用索引SQL记录 ...
- postman全局变量设置
1.点击小齿轮进入到变量添加页面,点击Globals添加全局变量 2.输入变量名称和变量值 3.接口中设置变量