举例:如Structs2框架中的FilterChain过滤器链,当如果需要对一个字符串进行多次不同的处理,都属于同一类的操作,但是注意过滤过程也许会有顺序的要求。
main函数
用极限编程,现在main函数中写测试函数,再写功能模块(这样也有利于从使用者的角度出发考虑代码设计)
极限编程:先写调用程序,再写功能模块。当你写完测试程序之后,就会发现写功能模块目标明确,很方便
package test;
public class main {
public static void main(String[] args) {
String str="李芬是个大傻逼!超级大3-8";
DataPocessor dp=new DataPocessor();
dp.setStr(str);
String s=dp.process();
System.out.print(s);
}
}
功能模块DataPocessor
拦截器是可以调整顺序的,如果写在配置文件中更爽,根本不需要修改代码
形成过滤器链,顺序可以调整,且新规则可以添加在任意位置上,哪个规则不需要了可以直接抽掉,链条上的东西可以来回进行组装
package test;
public class DataPocessor {
//责任链可以调整顺序,如果有配置文件就可以通过配置文件来修改责任链
private Filter[] filters={new HtmlFilter(),new minganFilter()};
private String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public String process(){
String r=str;
//形成过滤器链,依次处理
for(Filter filter:filters){
r=filter.doFilter(r);
}
return r;
}
}
编写过滤器接口
多态所带来的最重要的好处就是可扩展性(父类、接口、抽象类可以接收其子类、实现类、具体类)
使用接口写拦截器实现类实现可扩展性
package test;
public interface Filter {
public String doFilter(String str);
}
编写过滤器实现类
package test;
//HtmeFilter过滤器
public class HtmlFilter implements Filter {
public HtmlFilter(){}
@Override
public String doFilter(String str) {
// TODO Auto-generated method stub
String s=str.replace("傻逼", "**");
return s;
}
}
package test;
public class minganFilter implements Filter {
//minganFilter过滤器
@Override
public String doFilter(String str) {
// TODO Auto-generated method stub
return str.replace("3-8", "??");
}
}
以上设计模式形成一个简单的责任链,但是如果想要在该责任链中添加、删除过滤器,或者在原先责任链的中间或某个地方插入一些过滤器或者一条过滤器链,就需要对这些过滤器进行管理。比如,一条过滤器链里想要插入另一条过滤器链,那么就可以把FilterChain实现Filter接口,把FilterChain本身也看成一个大的Filter。
增加一个FilterChain类来专门管理责任链,自身也为一个大的Filter
package test;
import java.util.ArrayList;
import java.util.List;
public class FilterChain implements Filter{
private List<Filter> filters=new ArrayList<Filter>();
public List<Filter> getFilters() {
return filters;
}
public void setFilters(List<Filter> filters) {
this.filters = filters;
}
//责任链中添加过滤器,用方法链变成风格
public FilterChain addFilter(Filter filter){
filters.add(filter);
return this;
}
//每一个责任链内部有许多过滤器,那么内部需要dofilter
public String doFilter(String str){
String r=str;
for(Filter filter:filters){
r=filter.doFilter(r);
}
return r;
}
}
原先的DataProcessor功能模块类则变为
package test;
public class DataPocessor {
//不再使用Filter数组,而是改为直接引入责任链
//private Filter[] filters={new HtmlFilter(),new minganFilter()};
private FilterChain filterChain;
private String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public FilterChain getFilterChain() {
return filterChain;
}
public void setFilterChain(FilterChain filterChain) {
this.filterChain = filterChain;
}
//处理方式变为由filterChain自己处理
public String process(){
String r=filterChain.doFilter(str);
return r;
}
}
main测试
package test;
public class main {
public static void main(String[] args) {
String str="李芬是个大傻逼!超级大3-8";
DataPocessor dp=new DataPocessor();
dp.setStr(str);
FilterChain filterChain1=new FilterChain();
filterChain1.addFilter(new HtmlFilter())
.addFilter(new minganFilter());
FilterChain filterChain2=new FilterChain();
filterChain2.addFilter(new HtmlFilter());
//把第2条责任链加到原本的第1条责任链里
filterChain1.addFilter(filterChain2);
dp.setFilterChain(filterChain1);
String s=dp.process();
System.out.print(s);
}
}
用一个时序图表示该过程