[工作中的设计模式]责任链模式chain
一、模式解析
责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
责任链模式的要点主要是:
1、有多个对象共同对一个任务进行处理。
2、这些对象使用链式存储结构,形成一个链,每个对象知道自己的下一个对象。
3、一个对象对任务进行处理,可以添加一些操作后将对象传递个下一个任务。也可以在此对象上结束任务的处理,并结束任务。
3、客户端负责组装链式结构,但是客户端不需要关心最终是谁来处理了任务。
二、模式代码
1、创建处理器接口
- package chain.patten;
- /**
- * 责任链接口
- * @author zjl
- * @time 2016-2-11
- *
- */
- public abstract class Handler {
- //下一级责任链
- public Handler handler;
- //设置下一级责任链
- public void setSuccessor(Handler handler){
- this.handler=handler;
- }
- public abstract void request(int request);
- }
2、创建处理器对象1
- package chain.patten;
- public class ConcreteHandler1 extends Handler {
- @Override
- public void request(int request) {
- if(request<10){
- System.out.println("我是handler1,我处理了请求:"+request);
- }else {
- this.handler.request(request);
- }
- }
- }
3、创建处理器对象2
- package chain.patten;
- public class ConcreteHandler2 extends Handler {
- @Override
- public void request(int request) {
- if(request>10){
- System.out.println("我是handler2,我处理了请求:"+request);
- }else {
- System.out.println("请求"+request+"没人能处理");
- }
- }
- }
4、创建客户端
- package chain.patten;
- public class Client {
- public static void main(String[] args) {
- //创建处理器
- Handler handler1=new ConcreteHandler1();
- Handler handler2=new ConcreteHandler2();
- //客户端创建处理器的关联,形成链
- handler1.setSuccessor(handler2);
- //创建任务,此处为一些数字,不同大小,处理器处理结果不同
- int[] requests={4,10,59,2,16};
- //调用处理器处理
- for(int request:requests){
- handler1.request(request);
- }
- }
- }
5、执行结果
- 我是handler1,我处理了请求:4
- 请求10没人能处理
- 我是handler2,我处理了请求:59
- 我是handler1,我处理了请求:2
- 我是handler2,我处理了请求:16
三、应用场景
在工作中,尤其是java web开发中,有两个地方明显使用责任链模式,一个是filter,一个是listener,filter的自定义在web开发中可以对web请求做各种处理和过滤,包括:对请求和相应的字符集处理、对跨站脚本攻击的过滤、获取客户端真实ip地址、获取客户证书、防止盗链等等,在此处,简单模拟责任链模式对请求的处理。
四、场景代码
1、过滤器接口
- package chain.example;
- public abstract class Filter {
- //request 和response在真正的servlet中是对象,此处简化处理为string
- public abstract void doFilter(String request,String response,FilterChain filterChain);
- }
2、过滤器-处理字符集
- package chain.example;
- public class EncodeFilter extends Filter {
- @Override
- public void doFilter(String request, String response, FilterChain filterChain) {
- System.out.println("对request做utf-8编码");
- filterChain.doFilter(request, response);
- System.out.println("对response做utf-8编码");
- }
- }
3、过滤器-处理xss攻击
- package chain.example;
- public class XssFilter extends Filter {
- @Override
- public void doFilter(String request, String response, FilterChain filterChain) {
- System.out.println("过滤request的xss内容");
- filterChain.doFilter(request, response);
- System.out.println("过滤response的xss内容");
- }
- }
4、servlet接口,仅实现service接口
- package chain.example;
- public interface Servlet {
- public void service(String request,String response);
- }
5、定义一个servlet实现
- package chain.example;
- public class MainServlet implements Servlet {
- @Override
- public void service(String request, String response) {
- System.out.println(request);
- //为response赋值
- response="返回结果";
- System.out.println(response);
- }
- }
6、定义内部处理的filter链,链中保存真正filter的执行顺序,和servlet
- package chain.example;
- import java.util.ArrayList;
- import java.util.List;
- public class FilterChain {
- private int cursor;
- public List<Filter> filters=new ArrayList<Filter>();
- public Servlet servlet;
- public void setServlet(Servlet servlet){
- this.servlet=servlet;
- }
- public void addFilter(Filter filter){
- this.filters.add(filter);
- }
- public void doFilter(String request,String response){
- if(cursor<filters.size()){
- filters.get(cursor++).doFilter(request, response,this);
- }else {
- servlet.service(request, response);
- }
- }
- }
7、客户端代码
- package chain.example;
- public class Client {
- public static void main(String[] args) {
- //定义filter
- Filter encodeFilter=new EncodeFilter();
- Filter xssFilter=new XssFilter();
- FilterChain chain=new FilterChain();
- chain.addFilter(encodeFilter);
- chain.addFilter(xssFilter);
- //定义servlet
- Servlet servlet=new MainServlet();
- chain.setServlet(servlet);
- chain.doFilter("发送请求", "");
- }
- }
8.、执行结果
- 对request做utf-8编码
- 过滤request的xss内容
- 发送请求
- 返回结果
- 过滤response的xss内容
- 对response做utf-8编码
五、实例说明
filter的责任链实现与责任链模式的标准代码有着一定的差距,它具有如下特点:
1、责任链的实现并不是链式结构,而是以一个FilterChain保存了所有责任链的引用,通过FilterChain的doFilter方法依次调用filter进行执行;
2、filter中同时也保存了FilterChain的引用,形成了一个双向引用;
3、FilterChain作为web容器的功能,由系统默认提供,我们无需关注其实现原理(注:代码中仅为可能实现的方式)。他依次将web.xml中的filter按照文件排放顺序进行调用执行。
由此我们思考,责任链模式的实现应该有多种形式,可以为责任链之间的互相链式引用,也可以为第三方集合中的顺序执行方式,在我所接触最广泛的系统中,对责任链进行如下使用:在执行真正交易时候,根据模板选择责任链,在配置文件中定义了一些列的Command,由chain方法将其转化为一个list的责任链,然后使用迭代器依次执行,对系统的传递请求进行一些列操作,格式为:
- <chain id="chainForRoleControlDV">
- <commands>
- <ref>RuleBasedDynamicViewCommand</ref>
- <ref>roleControlCommand</ref>
- <ref>validationCommand</ref>
- <ref>ruleCommand</ref>
- <ref>delegateCommand</ref>
- <ref>${chain.monitor}</ref>
- </commands>
- </chain>
此种可以对请求进行登录控制,字段校验,权限控制,监控信息发送,验证码校验等一些列操作。这样只需要定义几个责任链可以完成对所有交易的区分控制。
[工作中的设计模式]责任链模式chain的更多相关文章
- C#设计模式-责任链模式(Chain of Responsibility Pattern)
引子 一个事件需要经过多个对象处理是一个挺常见的场景,譬如采购审批流程,请假流程,软件开发中的异常处理流程,web请求处理流程等各种各样的流程,可以考虑使用责任链模式来实现.现在以请假流程为例,一般公 ...
- 23种设计模式--责任链模式-Chain of Responsibility Pattern
一.责任链模式的介绍 责任链模式用简单点的话来说,将责任一步一步传下去,这就是责任,想到这个我们可以相当击鼓传花,这个是为了方便记忆,另外就是我们在项目中经常用到的审批流程等这一类的场景时我们就可以考 ...
- 设计模式-责任链模式Chain of Responsibility)
一.定义 职责链模式是一种对象的行为模式.在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道链 ...
- 乐在其中设计模式(C#) - 责任链模式(Chain of Responsibility Pattern)
原文:乐在其中设计模式(C#) - 责任链模式(Chain of Responsibility Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 责任链模式(Chain of R ...
- 二十四种设计模式:责任链模式(Chain of Responsibility Pattern)
责任链模式(Chain of Responsibility Pattern) 介绍为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求.将这些对象连成一条链,并沿着这条链传递该请求,直 ...
- 责任链模式-Chain of Responsibility(Java实现), 例2
责任链模式-Chain of Responsibility 在这种模式中,通常每个接收者都包含对另一个接收者的引用.如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推. 咱们在 ...
- 责任链模式-Chain of Responsibility(Java实现), 例1
责任链模式-Chain of Responsibility, 例1 在这种模式中,通常每个接收者都包含对另一个接收者的引用.如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推. ...
- java 设计模式 -- 责任链模式
设计模式 – 责任链模式 介绍: 责任链模式是一种动态行为模式,有多个对象,每一个对象分别拥有其下家的引用.连起来形成一条链.待处理对象则传到此链上,在此链进行传递,且待处理对象并不知道此会被链上的哪 ...
- Java与设计模式-责任链模式
责任链模式属于行为型设计模式之中的一个,怎么理解责任链?责任链是能够理解成数个对象首尾连接而成,每个节点就是一个对象.每个对象相应不同的处理逻辑,直至有一个对象响应处理请求结束.这一种模式成为责任链模 ...
随机推荐
- JQuery datepicker 日期控件设置
datepicker控件可通过参数设置进行语言切换,以下可实现,系统所有日期控件默认为中文,在特定页面或者特定条件下可切换成英语!~ HTML: <!DOCTYPE html> <h ...
- git操作---查询
1.查看git的状态 git status 2.查看git的日志历史记录 git log 3.查看当前git的分支 git branch 4.查看git的配置信息 git config --lis ...
- HTML5触摸事件(touchstart、touchmove和touchend) (转)
HTML5中新添加了很多事件,但是由于他们的兼容问题不是很理想,应用实战性不是太强,所以在这里基本省略,咱们只分享应用广泛兼容不错的事件,日后随着兼容情况提升以后再陆续添加分享.今天为大家介绍的事件主 ...
- WampServer 的phpmyadmin数据
WampServer首次安装的时候phpmyadmin的密码是为空 设置密码 1.安装成功后,通过 phpmyadmin 进入mysql,点击上面的 [用户] 菜单,在用户[root]主机[local ...
- yaml
YAML http://baike.baidu.com/link?url=Jqbh_SBnlVuP0dPCknzd5ti5jr4h9HcacA0j56ztf4QsPcXI8kvgFaKpvhRG3em ...
- FindWindowEx用法
函数原型:HWND FindWindowEx(HWND hwndParent,HWND hwndChildAfter,LPCTSTR lpszClass,LPCTSTR lpszWindow): 参数 ...
- Linux C 堆内存管理函数malloc()、calloc()、realloc()、free()详解
C 编程中,经常需要操作的内存可分为下面几个类别: 堆栈区(stack):由编译器自动分配与释放,存放函数的参数值,局部变量,临时变量等等,它们获取的方式都是由编译器自动执行的 堆区(heap):一般 ...
- 新语言代码高亮及Windows Live Writer插件开发
最近在博客园做一些学习笔记.一个是看apple的swift官方书,另外一个是随学校课堂(SICP)学习scheme. 这两种语言都谈不上普及(或者说swift太新).博客园原来的windows liv ...
- awk 双引号vs单引号
centos下面, awk '{...}' 和 awk "{...}" 差别是很大的: [ywt@YuWentao]$ echo "a b c d 1 2 3 4&quo ...
- Find All Numbers Disappeared in an Array
Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and ot ...