您的位置:首页 > 其它

设计模式初探-责任链模式

2017-08-08 09:16 246 查看
责任链模式(CHAIN OF RESPONSIBILITY),通过将多个对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它,属于对象行为型模式。责任链模式使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。JavaScript的事件处理,工作流系统中公文的多级审批,Web开发中的过滤器和拦截器都可以采用责任链模式实现。
一、使用场景
1、有多个对象可以处理同一个请求,具体哪个对象处理该请求需要等到运行时刻再确定。

2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。

3、可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求,还可以改变链中处理者之间的先后次序。 

二、UML图



三、Java实现

[java] view
plain copy

package study.patterns.chainofresponsibility;  

  

import java.util.ArrayList;  

import java.util.List;  

/** 

 * 对于实现责任链的访问处理顺序问题,该问题的解决使用的是递归的思想,从而使先调用的结点在处理返回结果时其调用过滤器的顺序是相反的。 

 * 这种解决方案在Struts和其他框架中实现过滤器和拦截器使用的较为普遍,并且十分巧妙。 

 * @author qbg 

 * 此处通过实现Web中经常采用的过滤器来演示责任链模式的原理和用法。 

 */  

public class ChainOfResponsibilityPattern {  

    public static void main(String[] args) {  

        String message = "敏感词汇,重庆,<script> 躲猫猫 :)";    

        Request request = new Request();    

        request.setRequestStr(message);    

        Response response = new Response();    

        response.setResponseStr("response");    

        FilterChain fc = new FilterChain();    

        fc.addFilter(new HTMLFilter()).addFilter(new SesitiveFilter());    

   

        FilterChain fc2 = new FilterChain();    

        fc2.addFilter(new FaceFilter());    

        fc.addFilter(fc2);//由于FilterChain也实现Filter接口,所以可以将一个FilterChain加入到另一个FilterChain中   

        fc.doFilter(request, response,fc);    

        System.out.println("request = " + request.getRequestStr());    

        System.out.println("response = " + response.getResponseStr());    

    }  

}  

/** 

 * 封装请求  

 */  

class Request {    

    String requestStr;    

   

    public String getRequestStr() {    

        return requestStr;    

    }    

   

    public void setRequestStr(String requestStr) {    

        this.requestStr = requestStr;    

    }    

}    

/** 

 * 响应:封装请求经过责任链后的处理结果  

 */  

class Response {    

    String responseStr;    

   

    public String getResponseStr() {    

        return responseStr;    

    }    

   

    public void setResponseStr(String responseStr) {    

        this.responseStr = responseStr;    

    }    

}    

/** 

 * 过滤器接口  

 */  

interface Filter {    

    public void doFilter(Request request, Response response,FilterChain chain);    

   

}   

/** 

 * 过滤器链 

 */  

class FilterChain implements Filter {    

    List<Filter> filters = new ArrayList<Filter>();//存放所有过滤器集合    

    int index = 0; //当前过滤器索引,用于判断过滤器链是否执行完毕  

   

    public FilterChain addFilter(Filter f) {    

        this.filters.add(f);    

        return this;    

    }    

   

    @Override   

    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);    

    }    

}   

/**   

 * 过滤HTML中的脚本元素   

 *   

 */   

class HTMLFilter implements Filter {    

   

    @Override   

    public void doFilter(Request request, Response response,FilterChain chain) {    

        request.requestStr = request.getRequestStr().replace("<", "[")    

                .replace(">", "] --------HTMLFilter");    

        chain.doFilter(request, response, chain);    

        response.responseStr += "--------HTMLFilter";    

            

    }    

}   

/** 

 * 过滤敏感词 

 */  

class SesitiveFilter implements Filter {    

       

    @Override   

    public void doFilter(Request request, Response response, FilterChain chain) {    

        request.requestStr = request.getRequestStr().replace("敏感", "  ")    

                .replace("猫猫", "haha------SesitiveFilter");    

        chain.doFilter(request, response, chain);    

        response.responseStr += "------SesitiveFilter";    

   

    }    

}  

/** 

 * 过滤表情符  

 */  

class FaceFilter implements Filter {    

    @Override   

    public void doFilter(Request request, Response response, FilterChain chain) {    

        request.requestStr = request.getRequestStr().replace(":)",    

                "^V^-------FaceFilter");    

        chain.doFilter(request, response, chain);    

        response.responseStr += "-------FaceFilter";    

   

    }    

}    

[plain] view
plain copy

request =   词汇,重庆,[script] --------HTMLFilter 躲haha------SesitiveFilter ^V^-------FaceFilter  

response = response-------FaceFilter------SesitiveFilter--------HTMLFilter  

四、模式优缺点
优点:
1、降低耦合度。职责链模式将请求处理细节(请求由哪些对象处理,怎样处理)跟客户端代码隔离开来,这些细节对客户端是透明的,客户端只需将相应的职责添加到链中即可,具体的处理过程交给责任链,降低了系统的耦合度。
2、增强了给对象指派职责的灵活性。可以通过在运行时对职责链进行动态的增加或修改来改变处理一个请求的职责,职责链的维护是客户端负责的,所以增加或修改责任链不影响类库代码,非常灵活。
缺点:
1、不保证请求被接受。由于责任链中的每个对象只处理自己感兴趣的请求,对于请求是否处理过并没有感知,这样容易导致请求没有对应的处理者。当一个请求的责任链没有正确配置时也会导致该请求得不到处理。
2、由于责任链模式请求处理的不确定性,所以加大了程序调试的难度。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: