Java模式开发之责任链模式
Java模式开发之责任链模式
从击鼓传花谈起
击鼓传花是一种热闹而又紧张的饮酒游戏。在酒宴上宾客依次坐定位置,由一人击鼓。击鼓的地方与传花的地方是分开的。以示公正。
開始击鼓时,花束就開始依次传递,鼓声一落,假设花束在某人手中,则该人就得饮酒。
假比说,贾母、贾赦、贾政、贾宝玉和贾环是五个參加击鼓传花游戏的传花者,他们组成一个环链。击鼓者将花传给贾母,開始传花游戏。花由贾母传给贾赦。由贾赦传给贾政,由贾政传给贾宝玉,又由贾宝玉传给贾环,由贾环传回给贾母,如此往复(见下图)。
当鼓声停止时。手中有花的人就得运行酒令。
击鼓传花便是责任链模式的应用。在责任链模式里,非常多的对象由每个对象对其下家的引用而联接起来形成一条链。
请求在这个链上传递。直到链上的某一个对象决定处理此请求。发出这个请求的client并不知道链上的哪一个对象终于处理这个请求。这使得系统能够在不影响client的情况下动态地又一次组织链和分配责任。
责任链可能是一条直线、一个环链甚至一个树结构的一部分。
责任链模式的结构
责任链模式是一种对象的行为模式。它所涉及到的角色例如以下:
第一、抽象处理者(Handler)角色、定义出一个处理请求的接口;假设须要,接口能够定义出一个方法,以返回对下家的引用。下图给出了一个示意性的类图:
图2、抽象处理者角色。
在图中的积累关系给出了详细子类对下家的引用。抽象方法handleRequest()规范了子类处理请求的操作。
第二、详细处理者(ConcreteHandler)角色、处理接到请求后,能够选择将请求处理掉,或者将请 求传给下家。下图给出了一个示意性的类图。
图3、详细处理者角色。
上图中的示意性的详细处理者ConcreteHandler类仅仅有handleRequest()一个方法。
责任链模式的静态类结构可见下图:
图4、责任链模式的类图定义。
纯的与不纯的责任链模式
一个纯的责任链模式要求一个详细的处理者对象仅仅能在两个行为中选择一个:一是承担责任,二是把责任推给下家。不同意出现某一个详细处理者对象在承担了一部分责任后又把责任向下传的情况。
在一个纯的责任链模式里面。一个请求必须被某一个处理者对象所接受;在一个不纯的责任链模式里面。一个请求能够终于不被不论什么接受端对象所接受。
纯的责任链模式的实际样例非常难找到,一般看到的样例均是不纯的责任链模式的实现。有些人觉得不纯的责任链根本不是责任链模式,这或许是有道理的。可是在实际的系统里,纯的责任链非常难找到;假设坚持责任链不纯便不是责任链模式,那么责任链模式便不会有太大的意义了。
责任链模式要求链上全部的对象都继承自一个共同的父类
在什么情况下使用责任链模式
在以下的情况下使用责任链模式:
第一、系统已经有一个由处理者对象组成的链。
这个链可能由复合模式给出。
第一、当有多于一个的处理者对象会处理一个请求。并且在事先并不知道究竟由哪一个处理者对象处理一个请求。
这个处理者对象是动态确定的。
第二、当系统想发出一个请求给多个处理者对象中的某一个,可是不明显指定是哪一个处理者对象会处理此请求。
第三、当处理一个请求的处理者对象集合须要动态地指定时。
使用责任链模式的好处和短处
责任链模式减低了发出命令的对象和处理命令的对象之间的耦合,它同意多与一个的处理者对象依据自己的逻辑来决定哪一个处理者终于处理这个命令。
换言之。发出命令的对象仅仅是把命令传给链结构的起始者,而不须要知道究竟是链上的哪一个节点处理了这个命令。
显然,这意味着在处理命令上,同意系统有很多其它的灵活性。哪一个对象终于处理一个命令能够由于由那些对象參加责任链、以及这些对象在责任链上的位置不同而有所不同。
责任链模式的实现
链结构的由来
值得指出的是。责任链模式并不创建出责任链。
责任链的创建必须有系统的其它部分完毕。
责任链模式减低了请求的发送端和接收端之间的耦合。使多个对象都有机会处理这个请求。一个链能够是一条线,一个树,也能够是一个环。链的拓扑结构能够是单连通的或多连通的,责任链模式并不指定责任链的拓扑结构。可是责任链模式要求在同一个时间里,命令仅仅能够被传给一个下家(或被处理掉);而不能够传给多于一个下家。在以下的图中,责任链是一个树结构的一部分。
图9、责任链是系统已有的树结构的一部分。图中有阴影的对象给出了一个可能的命令传播路径。
责任链的成员往往是一个更大的结构的一部分。比方在前面所讨论的《红楼梦》中击鼓传花的游戏中。全部的成员都是贾府的成员。假设责任链的成员不存在。那么为了使用责任链模式,就必须创建它们。责任链的详细处理者对象能够是同一个详细处理者类的实例。
在Java的1.0版的AWT事件处理模型里。责任链便是视窗上的部件的容器等级结构。
在以下会谈到的Internet Explorer的DHTML的DOM事件处理模型里,责任链则是DOM等级结构本身。
命令的传递
在一个责任链上传递的可能不仅仅有一个命令,而是数个命令。这些命令能够採取抽象化层、详细化层的多态性实现方式,见下图。从而能够将命令对象与责任链上的对象之间的责任分隔开,并将命令对象与传播命令的对象分隔开。
图10、多个命令在责任链上的传播。
样例:
FilterChain管理整个Filter,并且自己也继承Filter,这样就能够附加其它FilterChain
public class FilterChain implements Filter {
List<Filter> filters = new ArrayList<Filter>();
private int index = 0;
public FilterChain addFilter(Filter f) {
filters.add(f);
return this;
}
public void doFilter(Request request, Response response, FilterChain chain) {
if(index == filters.size()) return;
Filter f = filters.get(index);
index ++;
f.doFilter(request, response, chain);
}
}
public class HTMLFilter implements Filter {
public void doFilter(Request request, Response response, FilterChain chain) {
request.setRequestStr(request.getRequestStr().replace('<', '['));
request.setRequestStr(request.getRequestStr().replace('>', ']') + "---HTMLFilter()");
chain.doFilter(request, response, chain);
response.setResponseStr(response.getResponseStr() + "---HTMLFilter()");
}
}
本文借鉴。
出处:yesky责任编辑:方舟
Java模式开发之责任链模式的更多相关文章
- Java设计模式十九——责任链模式
责任链模式 老李的苦恼 每个人在出生的时候,都早已在暗中被标好了三六九等. 老李是一名建筑工地的木匠,和大多数生活在社会最底层的农民工一样,一辈子老实本分,胆小怕事.在他们的心中,谁当老爷都没有区别, ...
- Java设计模式系列之责任链模式
责任链模式 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道 ...
- 设计模式《JAVA与模式》之责任链模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其 ...
- 《java设计模式》之责任链模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其 ...
- 【转】《JAVA与模式》之责任链模式
<JAVA与模式>之责任链模式 在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模 ...
- Java常见设计模式之责任链模式
原文地址: http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html 在阎宏博士的<JAVA与模式>一书中开 ...
- 《JAVA与模式》之责任链模式
责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道链上的哪一个 ...
- 《JAVA设计模式》之责任链模式(Chain of Responsibility)
在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其 ...
- 《JAVA与模式》之责任链模式 【转载】
转载自java_my_life的博客 原文地址:http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html 在阎宏博士的&l ...
随机推荐
- Selenium2+python自动化61-Chrome浏览器(chromedriver)【转载】
前言 selenium2启动Chrome浏览器是需要安装驱动包的,但是不同的Chrome浏览器版本号,对应的驱动文件版本号又不一样,如果版本号不匹配,是没法启动起来的. 一.Chrome遇到问题 1. ...
- python类的__new__和__init__
python的类,和其他语言有一点不太一样,就是,他把新建一个类和初始化一个类,分成了两个方法: __new__ __init__ 当然,想想就知道,肯定是__new__先发生,然后才是__init_ ...
- 举例说明如何使用【聚合数据】的API接口
0 注册[聚合数据]的账号 登陆www.juhe.cn,如图,如果没有账号,注册一个(手机号或者邮箱注册),如果有直接登陆即可. 1 搜索所需的API接口 找到聚合数据主页,在搜索框输入你想搜索的AP ...
- c# WinForm窗体编程中对窗体程序设置快捷键
c# WinForm窗体编程中对窗体程序设置快捷键http://www.cnblogs.com/bison1989/archive/2011/09/19/2180977.html /// <su ...
- elasticsearch中client.transport.sniff的使用方法和注意事项
https://blog.csdn.net/J_bean/article/details/79507559
- Django使用普通表单、Form、以及modelForm操作数据库方式总结
Django使用普通表单.Form.以及modelForm操作数据库主要应用于增删该查的情景下,流程通用如下,只是实现方式不一样: 进入填写表单页面: 在表单页面填写信息,并提交: 表单数据验证 验证 ...
- [centos6.5]添加eclipse快捷方式
[Desktop Entry] Version=buzhidao Encoding=UTF-8 Name=eclipse Comment=eclipse-for-php Exec=/opt/eclip ...
- Fruit Feast(暴力)(动态规划)
Fruit Feast 时间限制: 1 Sec 内存限制: 64 MB提交: 64 解决: 18[提交][状态][讨论版] 题目描述 Bessie has broken into Farmer J ...
- Diamond Collector (动态规划)
问题 I: Diamond Collector 时间限制: 1 Sec 内存限制: 64 MB提交: 22 解决: 7[提交][状态][讨论版] 题目描述 Bessie the cow, alwa ...
- Floyd-弗洛伊德算法
今天,研究一下谁都能看懂的弗洛伊德算法. 首先,弗洛伊德算法是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法. 这个算法需要一个用到一个二维数组啊a[][],而a[i][j]表示的就 ...