最近了解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设计模式——责任链 等等