ChainOfResponsiblity责任链模式。
一系列对象之间的消息传递形成了线性的或循环的传递结构,例如A可以传给B,B可以传给C,C可以传给D……当条件不满足传递时,就停止传递。
例如,客户端对象发出一个请求给服务端处理,而客户端只知道服务端有n个服务对象可以对这个请求作出响应,但是客户端并不清楚哪个服务端对象是最合适处理这个请求的。最原始的处理方式,就是在客户端程序进行n个if else的语句判断。当服务端在添加一个服务处理对象时,便在客户端再添加一个if else,就这样如此循环不断的进行下去。
可见这样的代码的质量相当低劣,是如何的不高明,难以维护扩展。利用责任链的作法是,在客户端创建出那些可以对请求作出响应的服务端的对象实例,然后设置服务对象之间的传递关系,接着把请求消息传递给第一个服务对象,交给服务对象之间进行内部判断究竟哪个是适合作出响应的。其中服务对象之间的传递关系的实现,类似于单向链表的实现。
public abstract class Service{
private Service nextService;
public Service() {/*...*/}
public abstract void response(Request request);
public Service getNextService() {
return nextService;
}
public void setNextService(Service service) {
nextService = service;
};
}
class FService extends Service {
private int flag = 1;
public FService() {/*...*/}
public void response(Request request) {
int flag = request.getFlag();
if (flag == this.flag) {
System.out.println("响应");
} else {
getNextService().response(request);
}
}
}
class SService extends Service {
private int flag = 2;
public SService() {/*...*/}
public void response(Request request) {
int flag = request.getFlag();
if (flag == this.flag) {
System.out.println("响应");
} else {
getNextService().response(request);
}
}
}
public class Client{
private static Request request = null;
private static FService fs = null;
private static SService ss = null;
public static void main(String[] args) {
request = new Request(2);
fs = new FSservice();
ss = new SService();
fs.setNextService(ss);
fs.response(request );
}
}
class Request{
prviate int flag;
public Request(int flag){this.flag = flag;}
public int getFlag(){return this.flag;}
}
其实,以servlet中的filter作为责任链的经典例子,是最好不过的了。过滤器的实现跟上面的例子有所不同,首先每个过滤器向一个过滤器链的管理器FilterChain注册,在每个过滤器Filter的doFilter(ServletRequest request,ServletResponse response,FilterChain chain)方法里面调用FilterChain的chain.doFilter(request,response);方法,由FilterChain实现调用下一个过滤器。实现的代码大概如下:
public interface Filter{
public void init(FilterConfig config) throws ServletException;
public void doFilter(ServletRequest srequest,ServletResponse sresponse,FilterChain chain)throws IOException,ServletException;
public void destroy();
}
public FilterChain{
private List list = new Vector();
private int currentFilter = 0;
private int totalFilter = 0;
public void addFilter(Filter filter){
list.add(filter);
totalFilter++;
}
public void doFilter(ServletRequest request,ServletResponse response){
/*......*/
if(currentFilter==totalFilter)
return;
((Filter)list.get(currentFilter++)).doFilter();
/*......*/
}
}
public class MyFilter implements Filter {
public void init(FilterConfig config) throws ServletException {/*...*/}
public void destroy(){/*...*/}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException,ServletException {/*...*/chain.doFilter();}
}