美文网首页
【设计模式】Filter-Chain 的应用

【设计模式】Filter-Chain 的应用

作者: lsfire | 来源:发表于2016-10-14 16:47 被阅读0次

Filter-Chain模式简介

从7月份实习以来,因为项目中运用alibaba DRUID 数据库中间件、Spring Framework等开源框架,所以就稍微阅读了部分源码,果然优秀的架构就是优秀的架构,学习里面对设计模式的应用,应该会对设计模式有更加深刻的理解。

Druid中增加模块就是通过Filter-Chain模式实现的,任何模块只要实现Filter接口里定义的方法,并在初始化时add,就可以对数据的Connection、Statement、ResultSet等做出处理。

下面用一个很简单的demo简单演示filter-chain模式的执行过程:

定义Filter接口

public interface Filter {

void doFilter(MyRequest request,MyResponse response,FilterChain chain);

}

其中MyRequestMyResponse 是自定义类型,模拟请求过程,当然MyRequest和MyResponse可以被替换成任意一种类型。

public class MyRequest {

StringBuffer content;

public MyRequest() {

content = new StringBuffer("request");

}

public MyRequest(String content){

this.content = new StringBuffer(content);

}

public StringBuffer getContent() {

return content;

}

public void setContent(String content) {

this.content = new StringBuffer(content);

}

public void append(String append){

this.content.append(append);

}

}
public class MyResponse {

private StringBuffer content;

public MyResponse() {

content = new StringBuffer("response");

}

public MyResponse(String content){

this.content = new StringBuffer(content);

}

public StringBuffer getContent() {

return content;

}

public void setContent(String content) {

this.content = new StringBuffer(content);

}

public void append(String append){

this.content.append(append);

}

}

实现Filter接口

每一个具体的Filter实现Filter接口中定义的doFilter方法,并在方法体中封装处理逻辑。

第一个具体的Filter类,这里完全简化处理逻辑,需要根据具体场景定义处理逻辑。实现类处理完自身职责范围的逻辑后,将对象传递给FilterChain,调用FilterChainDoFilter方法,FilterChain做为中介将对象传递给下一个Filter,稍后我们来看FilterChain这个类的实现。


public class FirstFilter implements Filter{

@Override

public void doFilter(MyRequest request, MyResponse response, FilterChain chain) {

request.append(" firsrt Filter || ");

chain.doFilter(request, response);

response.append(" firsrt Filter || ");

}

}

第二个具体的Filter类:

public class SecondFilter implements Filter{

@Override

public void doFilter(MyRequest request, MyResponse response, FilterChain chain) {

request.append("second filter || ");

chain.doFilter(request, response);

response.append("second filter || ");

}

}

FilterChain的实现

filterChain持有一个List的引用,并通过一个pos标志位标记执行到哪一个FilterChainDoFilter方法实际上就是将对象传递给Filter,并将标志位+1,指向下一个将要执行的Filter

public class FilterChain{

private List filters;

int pos = 0;

public FilterChain() {

filters = new LinkedList<>();

}

public void addFilter(Filter filter){

filters.add(filter);

}

public void doFilter(MyRequest request, MyResponse response) {

if(pos < filters.size()){

filters.get(pos++).doFilter(request, response, this);

}

}

}

两种实现方式

上面所述的实现方式是Tomcat、Spring、java web api中的实现方式。当然更简单的实现方式是每个filter持有下一个filter的引用,处理完之后直接调用nextFilter的方法,直到执行完毕。显然第二种在编码上更简单也更容易理解。那为什么许多java框架要采用第一种设计呢?个人认为第一种显然在可扩展上要优于第二种实现。FilterChain持有Filter的列表,自然拥有对所有Filter的管理和控制。这样就把对整个filter-Chain链的管理集中在一个地方,实现了维护和扩展的方便。

相关文章

网友评论

      本文标题:【设计模式】Filter-Chain 的应用

      本文链接:https://www.haomeiwen.com/subject/ntxnyttx.html