(转)职责链设计模式(Chain of Responsibility)
Chain of Responsibility定义
Chain of Responsibility(CoR) 是用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合,唯一共同点是在他们之间传递request. 也就是说,来了一个请求,A类先处理,如果没有处理,就传递到B类处理,如果没有处理,就传递到C类处理,就这样象一个链条(chain)一样传递下去。过滤器就用到了。
如何使用?
虽然这一段是如何使用CoR,但是也是演示什么是CoR.
有一个Handler接口:
public interface Handler{
public void handleRequest();
}
这是一个处理request的事例, 如果有多种request,比如 请求帮助 请求打印 或请求格式化:
最先想到的解决方案是:在接口中增加多个请求:
public interface Handler{
public void handleHelp();
public void handlePrint();
public void handleFormat();
}
具体是一段实现接口Handler代码:
public class ConcreteHandler implements Handler{
private Handler successor;
public ConcreteHandler(Handler successor){
this.successor=successor;
}
public void handleHelp(){
//具体处理请求Help的代码
...
}
public void handlePrint(){
//如果是print 转去处理Print
successor.handlePrint();
}
public void handleFormat(){
//如果是Format 转去处理format
successor.handleFormat();
}
}
一共有三个这样的具体实现类,上面是处理help,还有处理Print 处理Format这大概是我们最常用的编程思路。
虽然思路简单明了,但是有一个扩展问题,如果我们需要再增加一个请求request种类,需要修改接口及其每一个实现。
原文链接:http://www.jdon.com/designpatterns/cor.htm
第二方案:将每种request都变成一个接口,因此我们有以下代码 :
public interface HelpHandler{
public void handleHelp();
}
public interface PrintHandler{
public void handlePrint();
}
public interface FormatHandler{
public void handleFormat();
}
public class ConcreteHandler
implements
HelpHandler,PrintHandler,FormatHandlet{
private HelpHandler helpSuccessor;
private PrintHandler printSuccessor;
private FormatHandler formatSuccessor;
public ConcreteHandler(HelpHandler helpSuccessor,PrintHandler printSuccessor,FormatHandler formatSuccessor)
{
this.helpSuccessor=helpSuccessor;
this.printSuccessor=printSuccessor;
this.formatSuccessor=formatSuccessor;
}
public void handleHelp(){
.......
}
public void handlePrint(){this.printSuccessor=printSuccessor;}
public void handleFormat(){this.formatSuccessor=formatSuccessor;}
}
这个办法在增加新的请求request情况下,只是节省了接口的修改量,接口实现ConcreteHandler还需要修改。而且代码显然不简单美丽。
解决方案3: 在Handler接口中只使用一个参数化方法:
public interface Handler{
public void handleRequest(String request);
}
那么Handler实现代码如下:
public class ConcreteHandler implements Handler{
private Handler successor;
public ConcreteHandler(Handler successor){
this.successor=successor;
}
public void handleRequest(String request){
if (request.equals("Help")){
//这里是处理Help的具体代码
}else
//传递到下一个
successor.handle(request);
}
}
}
这里先假设request是String类型,如果不是怎么办?当然我们可以创建一个专门类Request
最后解决方案:接口Handler的代码如下:
public interface Handler{
public void handleRequest(Request request);
}
Request类的定义:
public class Request{
private String type;
public Request(String type){this.type=type;}
public String getType(){return type;}
public void execute(){
//request真正具体行为代码
}
}
那么Handler实现代码如下:
public class ConcreteHandler implements Handler{
private Handler successor;
public ConcreteHandler(Handler successor){
this.successor=successor;
}
public void handleRequest(Request request){
if (request instanceof HelpRequest){
//这里是处理Help的具体代码
}else if (request instanceof PrintRequst){
request.execute();
}else
//传递到下一个
successor.handle(request);
}
}
}
这个解决方案就是CoR, 在一个链上,都有相应职责的类,因此叫Chain of Responsibility.
CoR的优点:
因为无法预知来自外界(客户端)的请求是属于哪种类型,每个类如果碰到它不能处理的请求只要放弃就可以。
缺点是效率低,因为一个请求的完成可能要遍历到最后才可能完成,当然也可以用树的概念优化。 在Java AWT1.0中,对于鼠标按键事情的处理就是使用CoR,到Java.1.1以后,就使用Observer代替CoR
扩展性差,因为在CoR中,一定要有一个统一的接口Handler.局限性就在这里。
与Command模式区别:
Command 模式需要事先协商客户端和服务器端的调用关系,比如 1 代表 start 2 代表 move 等,这些 都是封装在 request 中,到达服务器端再分解。
CoR 模式就无需这种事先约定,服务器端可以使用 CoR 模式进行客户端请求的猜测,一个个猜测 试验。
一段代码:
该代码实现了依次调用所有过滤器类的过滤方法的前半部分然后调用Action最后再倒过来调用所有过滤器的过滤方法的后半部分。
过滤器接口:
public interface Interceptor {
public void intercept(ActionInvocation invocation) ;
}
入口:
public class Main {
public static void main(String[] args) {
new ActionInvocation().invoke();
}
}
过滤器调用控制器:
import java.util.ArrayList;
import java.util.List;
public class ActionInvocation {
List<Interceptor> interceptors = new ArrayList<Interceptor>();
int index = -1;
Action a = new Action();
public ActionInvocation() {
this.interceptors.add(new FirstInterceptor());
this.interceptors.add(new SecondInterceptor());
}
public void invoke() {
index ++;
if(index >= this.interceptors.size()) {
a.execute();
}else {
this.interceptors.get(index).intercept(this);
}
}
}
两个过滤器:
public class FirstInterceptor implements Interceptor {
public void intercept(ActionInvocation invocation) { System.out.println(1); invocation.invoke(); System.out.println(-1); }
}
public class SecondInterceptor implements Interceptor {
public void intercept(ActionInvocation invocation) { System.out.println(2); invocation.invoke(); System.out.println(-2); }
}
要过滤的Action:
public class Action {
public void execute() {
System.out.println("execute!");
}
}
(转)职责链设计模式(Chain of Responsibility)的更多相关文章
- atitit.设计模式(1)--—职责链模式(chain of responsibility)最佳实践O7 日期转换
atitit.设计模式(1)---职责链模式(chain of responsibility)最佳实践O7 日期转换 1. 需求:::日期转换 1 2. 可以选择的模式: 表格模式,责任链模式 1 3 ...
- 设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型)
设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决,不能解决就 ...
- 设计模式的征途—14.职责链(Chain of Responsibility)模式
相信大家都玩过类似于“斗地主”的纸牌游戏,某人出牌给他的下家,下家看看手中的牌,如果要不起,则将出牌请求转发给他的下家,其下家再进行判断.一个循环下来,如果其他人都要不起该牌,则最初的出牌者可以打出新 ...
- 责任链模式 职责链模式 Chain of Responsibility Pattern 行为型 设计模式(十七)
责任链模式(Chain of Responsibility Pattern) 职责链模式 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系 将这些对象连接成一条链,并沿着这 ...
- 设计模式 ( 十二 ) 职责链模式(Chain of Responsibility)(对象行为)
设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决.不能解决就 ...
- 职责链模式(Chain of Responsibility)(对象行为型)
1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决,不能解决就推卸给另外个一个部门(对象).至于到底谁来解决这个问题呢?政府部门就是为了可以避免屁民的请求与 ...
- 设计模式之职责链模式(Chain of Responsibility)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- 行为型设计模式之职责链模式(Chain of Responsibility)
结构 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 适用性 有多个的对象可以处理一个请求,哪个 ...
- 重温设计模式(三)——职责链模式(chain of responsibility)
一. 写在前面的 这么多的设计模式,我觉得职责链是我第一次看上去最简单,可是回想起来却又最复杂的一个模式. 因此,这个文章我酝酿了很久,一直也没有胆量发出来,例子也是改了又改,可是仍然觉得不够合理.所 ...
- 设计模式:职责链模式(Chain of Responsibility)
去年参加校招要到长沙来,这个对于我来说不是特别喜欢(但又必须的来,谁叫咱不是985.211的娃呢),但是对于某些人来说就是福音了.大四还有课,而且学校抓的比较严,所以对于那些想翘课的人来说这个是最好不 ...
随机推荐
- PHP单例类
单例模式按字面来看就是某一个类只有一个实例,这样做的好处还是很大的,比如说数据库的连接,我们只需要实例化一次,不需要每次都去new了,这样极大的降低了资源的耗费. 单例类至少拥有以下三种公共元素: 必 ...
- C++中的读入输出优化及清新脱俗的宏命令
C和C++有了#define,从此它就变了模样 宏命令就是#define,#if,#error之类的 本文主要介绍宏命令和相关的骚操作 读入输出优化 inline int read() { int a ...
- [Arc062] Painting Graphs with AtCoDeer
[Arc062] Painting Graphs with AtCoDeer Description 给定一张N点M边的无向图,每条边要染一个编号在1到K的颜色.你可以对一张染色了的图进行若干次操作, ...
- BZOJ 2430 [Poi2003]Chocolate(贪心+归并排序)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2430 [题目大意] 有一块n*m的矩形巧克力,准备将它切成n*m块. 巧克力上共有n- ...
- [UOJ409]Highway Tolls
题意:交互题,给定一个简单无向图和$A,B(1\leq A\lt B)$,你可以对每条边指定其边权为$A$或$B$后通过交互库询问$S\rightarrow T$的最短路($S,T$在程序运行之前已经 ...
- 【枚举】XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016 Problem D. Cutting Potatoes
题意:有n个土豆,每个有体积V(i),你可以将每个土豆等分为不超过K份,问你最大块和最小块比值最小为多少. 直接枚举切法,只有n*K种,然后保证其为最大块,去算其他块的切法,即让其他块切得尽可能大即可 ...
- 【模拟退火】poj2420 A Star not a Tree?
题意:求平面上一个点,使其到给定的n个点的距离和最小,即费马点. 模拟退火的思想是随机移动,然后100%接受更优解,以一定概率接受更劣解.移动的过程中温度缓慢降低,接受更劣解的概率降低. 在网上看到的 ...
- Manthan, Codefest 16 G. Yash And Trees dfs序+线段树+bitset
G. Yash And Trees 题目连接: http://www.codeforces.com/contest/633/problem/G Description Yash loves playi ...
- iOS图片相似度比较
1. 缩小尺寸:将图像缩小到8*8的尺寸,总共64个像素.这一步的作用是去除图像的细节,只保留结构/明暗等基本信息,摒弃不同尺寸/比例带来的图像差异: 注:实际操作时,采取了两种尺寸作对比( ...
- Mysql双主实战
参考:http://dev.mysql.com/doc/refman/5.1/en/replication-options-slave.htmlhttp://blog.chinaunix.net/ui ...