java设计模式之—责任链模式 ChainOfResponsibility(提供两套方案)

概述:责任链模式,我们最常见的就是拦截器、过滤器。其中:拦截器、过滤器实现方式一样,并无本质区别,换汤不换药的。

举例说明:

String msg="大家好:),<script> 被就业,敏感,一个人学习到深夜";

要求:

1、把上面这句话中的特殊字符(前后尖括号)、笑脸:)、特殊敏感词汇(“敏感”),分别用不同的过滤器给过滤掉,并输出到控制台。

2、在实现上述功能的基础上,逆向调用责任链中的方法,逆向处理服务器响应数据。例如:服务器返回的信息是“response”。

  即是:处理request时,依次调用 过滤器 A  ---> B ---->   C.处理Response时,依次调用  过滤器 C  ---> B ---->   A

具体实现如下:

一:先实现第一个Demo (代码都写在 包com.xp.chain.responsibility.demo1 中)

1、创建过滤类接口,及其实现类:

//过滤类/拦截器超类
interface SuperFilter {
	public String doFilter(String str);
}


public class SonHtmlFilter implements SuperFilter {
	@Override
	public String doFilter(String str) {
		return str.replace("<", "[").replace(">", "]");
	}
}

public class SonFaceFilter implements SuperFilter {
	@Override
	public String doFilter(String str) {
		return str.replace(":)", "^_^");
	}
}

public class SonSensitiveFilter implements SuperFilter {
	@Override
	public String doFilter(String str) {
		return str.replace("敏感", "**");
	}
}

2、创建过滤类的容器,也就是所谓的责任链容器,并让容器本身也实现SuperFilter接口。


//过滤链条类(名字是汉语拼音,为了区分版本二的ChainFilter)
//该类即是过滤器接口和拦截器子类(实现类)的中间人,该类也继承了过滤器接口。(本身即是过滤器,同时还可以作为过滤器的容器)
public class LianTiaoFilter implements SuperFilter {
	
	List<SuperFilter> filters=new ArrayList<SuperFilter>();
	
	@Override
	public String doFilter(String str) {
		//循环遍历出各个过滤类的具体实现类,并执行过滤方法
		for (SuperFilter superFilter : filters) {
			str=superFilter.doFilter(str);
		}
		return str;
	}

	//提供容器扩展方法,remove暂不考虑
	public LianTiaoFilter addFilter(SuperFilter filter) {
		filters.add(filter);
		return this;//返回过滤器本身
	}
}

3、创建测试类,并在Main方法中,测试Demo结果

public class MainTest {

	public static void main(String[] args) {
		String msg="大家好:),<script> 被就业,敏感,一个人学习到深夜";
		LianTiaoFilter filters=new LianTiaoFilter();
		
		filters.addFilter(new SonHtmlFilter()).addFilter(new SonFaceFilter()).addFilter(new SonSensitiveFilter());//正因为容器本身实现了过滤器父类接口,所以可以连着写
		String string=filters.doFilter(msg);
		System.out.println(string);
	}

}

4、控制台输出结果如下:

大家好^_^,[script] 被就业,**,一个人学习到深夜

 

二:第二个Demo (代码都写在 包com.xp.chain.responsibility.demo2 中)。

注:前几个步骤和Demo1非常类似,比较难以理解的是,在同一个过滤器内,同时处理请求数据和返回数据。这个比较难,拿到代码后,打断点,就可以发现其中的奥妙。

1、创建Request类和Response类,为了模拟servler的底层实现。

//请求类
public class Request {
	public String requestStr;

	public String getRequestStr() {
		return requestStr;
	}

	public void setRequestStr(String requestStr) {
		this.requestStr = requestStr;
	}	
}

//响应类
public class Response {
	public String responseStr;

	public String getResponseStr() {
		return responseStr;
	}

	public void setResponseStr(String responseStr) {
		this.responseStr = responseStr;
	}	
}

2、创建过滤类父类和其实现类(代码看着长,里面的逻辑比较简单,自己打断点尝试一下)

interface Filter {
	void doFilter(Request request,Response response,ChainFilter chain);
}

//Html标签过滤类
public class HtmlFilter implements Filter {

	@Override
	public void doFilter(Request request, Response response, ChainFilter chain) {
	 
		request.requestStr=request.requestStr.replace("<", "[").replace(">", "]")+"---HtmlFiter()";//添加尾巴为了方便看执行结果
		
		//循环调用,处理request信息,直至结束后,才会执行下面response的代码。通过打断点调试可以看一下
		chain.doFilter(request, response, chain);
		
		response.responseStr+="---HtmlFiter()";//添加尾巴为了方便看执行结果
		
	}

}

//特殊符号过滤类
public class FaceFilter implements Filter {

	@Override
	public void doFilter(Request request, Response response, ChainFilter chain) {
		
		request.requestStr=request.requestStr.replace(":)", "^_^")+"---FaceFilter()";
		
		//循环调用,处理request信息,直至结束后,才会执行下面response的代码。通过打断点调试可以看一下
		chain.doFilter(request, response, chain);
		
		response.responseStr+="---FaceFilter()";
	}

}

//敏感词汇过滤类
public class SensitiveFilter implements Filter {

	@Override
	public void doFilter(Request request, Response response, ChainFilter chain) {
		request.requestStr=request.requestStr.replace("敏感", "**")+"---SensitiveFilter()";
		
		//循环调用,处理request信息,直至结束后,才会执行下面response的代码。通过打断点调试可以看一下
		chain.doFilter(request, response, chain);
		
		response.responseStr+="---SensitiveFilter()";
	}

}

注:细心的小伙伴,会很好奇(自己可以尝试调换顺序后运行一下):

    chain.doFilter(request, response, chain);        
      response.responseStr+="---HtmlFiter()";

上述这两行代码调换顺序后,会发生什么后果。(后果是:达不到逆向调用过滤类处理相应数据)

3、创建过滤器容器,下面这段代码比较绕口。可以打断点看一下。

public class ChainFilter implements Filter {
	List<Filter> filters=new ArrayList<Filter>();
	int index = 0;
	@Override
	public void doFilter(Request request, Response response, ChainFilter chain) {
		if (index==filters.size()) {
			return;
		}
		Filter filter = filters.get(index);
		index ++;
		filter.doFilter(request, response, chain);
	}


	public ChainFilter addFilter(Filter filter) {
		this.filters.add(filter);		
		return this;
	}
}

4、创建测试类,测试Demo运行结果。

public class MainFilter {

	/**
	 * 该测试方法目的,正向过滤请求数据的同时,反向处理响应数据
	 * @param args
	 */
	public static void main(String[] args) {
		String msg="大家好:),<script> 被就业,敏感,一个人学习到深夜";
		
		ChainFilter filters=new ChainFilter();
		filters.addFilter(new HtmlFilter()).addFilter(new FaceFilter()).addFilter(new SensitiveFilter());
		Request request=new Request();
		Response response=new Response();
		request.setRequestStr(msg);
		response.setResponseStr("response");
		filters.doFilter(request, response, filters);
		
		System.out.println(request.getRequestStr());
		System.out.println(response.getResponseStr());
	}
	
}

5、运行结果如下:

大家好^_^,[script] 被就业,**,一个人学习到深夜---HtmlFiter()---FaceFilter()---SensitiveFilter()
response---SensitiveFilter()---FaceFilter()---HtmlFiter()

后记:

这个例子,即使听马士兵老师的视频课,也比较生涩难懂。拿到代码后,自己多琢磨一下,打断点运行一下。并参考下图,领会其中的精髓。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值