设计模式-责任链模式

        最近了解druid时候,碰到这种设计模式,了解了一下,做个记录。

1、原理

      使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链。并沿着这条链传递该请求,直到有一个对象处理它为止。在这个链上的所有的对象有相同的接口(抽象类)但却有不同的实现。

设计模式-责任链模式


常见应用:javax.servlet.Filter#doFilter()

参与者:
•抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义出一个方法,以设定和返回对后继对象的引用。这个角色通常由一个抽象类或接口实现。
•具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给后继对象。由于具体处理者持有对后继对象的引用,因此,如果需要,具体处理者可以访问后继对象。


2、实例


/**
 * 抽象处理者角色
 * User: wayne
 * Date: 12-11-8
 * Time: 下午5:52
 */
public interface Filter {
    public void doFilter(MyRequest request,MyResponse response,MyFilterChain filterChain);
}
定义三个具体处理角色:字符过滤器、登录过滤器、权限过滤器



/**
 * 具体处理角色
 * User: wayne
 * Date: 12-11-8
 * Time: 下午6:02
 */
public class AuthFilter implements Filter{
    @Override
    public void doFilter(MyRequest request, MyResponse response, MyFilterChain filterChain) {
        request.setReqStr(request.getReqStr()+"[进行了权限过滤]");
        filterChain.doFilter(request,response,filterChain);
        response.setResp(response.getResp()+"[进行了权限过滤返回]");
    }
}
/**
 * 具体处理角色
 * User: wayne
 * Date: 12-11-8
 * Time: 下午6:02
 */
public class EncodeFilter implements Filter{
    @Override
    public void doFilter(MyRequest request, MyResponse response, MyFilterChain filterChain) {
        request.setReqStr(request.getReqStr()+"[进行了编码过滤]");
        filterChain.doFilter(request,response,filterChain);
        response.setResp(response.getResp()+"[进行了编码过滤返回]");
    }
}
/**
 * 具体处理角色
 * User: wayne
 * Date: 12-11-8
 * Time: 下午6:02
 */
public class LoginFilter implements Filter{
    @Override
    public void doFilter(MyRequest request, MyResponse response, MyFilterChain filterChain) {
        if(request.getReqStr().contains("root")){
            request.setReqStr(request.getReqStr()+"[进行了登录过滤]");
            filterChain.doFilter(request,response,filterChain);
            response.setResp(response.getResp()+"[进行了登录过滤返回]");
        } else{
            request.setReqStr(request.getReqStr()+"[进行了登录过滤:登录不成功]");
            response.setResp(response.getResp()+"[进行了登录过滤返回:登录失败]");
        }

    }
}
定义一根链子做串联用,这里注意这根链子也实现了Filter接口,这个的作用可以实现链子里面套链子
/**
 * 责任链
 * User: wayne
 * Date: 12-11-8
 * Time: 下午5:53
 */
public class MyFilterChain implements Filter{
    private List<Filter> filters = new LinkedList<Filter>();

    private MyRequest request;
    private MyResponse response;
    int index = 0;


    public MyFilterChain() {
    }

    public MyFilterChain(MyRequest request, MyResponse response) {
        this.request = request;
        this.response = response;
    }

    public void addFilter(Filter filter){
        this.filters.add(filter);
    }
    @Override
    public void doFilter(MyRequest request, MyResponse response, MyFilterChain filterChain) {
        if(index == filters.size())
            return;
        Filter filter = filters.get(index++);
        filter.doFilter(request,response,this);
    }

    public MyRequest getRequest() {
        return request;
    }

    public void setRequest(MyRequest request) {
        this.request = request;
    }

    public MyResponse getResponse() {
        return response;
    }

    public void setResponse(MyResponse response) {
        this.response = response;
    }
}
工具类
/**
 * 模拟请求
 * User: wayne
 * Date: 12-11-8
 * Time: 下午5:53
 */
public class MyRequest {
    private String reqStr;


    public String getReqStr() {
        return reqStr;
    }


    public void setReqStr(String reqStr) {
        this.reqStr = reqStr;
    }
}
/**
 * 模拟响应
 * User: wayne
 * Date: 12-11-8
 * Time: 下午5:53
 */
public class MyResponse {
    private String resp;


    public String getResp() {
        return resp;
    }


    public void setResp(String resp) {
        this.resp = resp;
    }

 
 

 

 
  
  
  
  
提供一个客户端
/**
 * 责任链模式
 * User: wayne
 * Date: 12-11-8
 * Time: 下午6:05
 */
public class Client {
    /**
     * 请求链:进入活动中心:[进行了编码过滤][进行了登录过滤][进行了权限过滤]
     * 回应链:进入活动中心:[进行了权限过滤返回][进行了登录过滤返回][进行了编码过滤返回]
     *
     * 请求链:进入活动中心:[进行了编码过滤][进行了登录过滤:登录不成功]
     * 回应链:进入活动中心:[进行了登录过滤返回:登录失败][进行了编码过滤返回]
     *
     * @param args
     */
    public static void main(String[] args){
        String reqMsg = "进入活动中心:";
        MyRequest request = new MyRequest();
        request.setReqStr(reqMsg);
        String reqsMsg = "响应进入中心:";
        MyResponse response = new MyResponse();
        response.setResp(reqMsg);


        MyFilterChain chain = new MyFilterChain();
        chain.addFilter(new EncodeFilter());
        chain.addFilter(new LoginFilter());
        chain.addFilter(new AuthFilter());


        chain.doFilter(request,response,chain);
        System.out.println("请求链:"+request.getReqStr());
        System.out.println("回应链:"+response.getResp());
    }
}


至此,一个简单的责任链就实现了。


3、优点:
•责任链模式降低了请求的发送端和接收端之间的耦合,使多个对象都有机会处理这个请求。
•由于是在客户端来定义责任链的结构,可以动态地增加或修改处理一个请求的结构,增强了给对象指派职责的灵活性。
4、适用场合:
•有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
•想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。 
•可处理一个请求的对象集合应被动态指定。
•当一个方法的传入参数将成为分支语句的判断条件,分支条件存在扩展的可能,每一个分支的职责相对独立,且逻辑较为复杂时。
5、缺点

此处欢迎补充。

6、疑问

    降低了请求的发送端和接收端之间的耦合这句,能否举个实际的例子?

   此模式的缺点有哪些呢?

7、资料

    设计模式学习总结-责任链模式(Chain of Responsibility Method)    

    java设计模式——责任链   等等



你可能感兴趣的:(责任链)