Java設(shè)計(jì)模式:責(zé)任鏈
責(zé)任鏈模式(Chain of Responsibility)的目標(biāo)是使多個(gè)對(duì)象都有機(jī)會(huì)處理請求,從而避免請求的發(fā)送者和接收者之間的耦合關(guān)系。將這些對(duì)象連成一條鏈,并沿著這條鏈傳遞請求,直到有一個(gè)對(duì)象處理它為止。
在處理用戶的請求時(shí)可能要根據(jù)不同的情況對(duì)請求添加不同的處理邏輯,在這時(shí)候就可以利用責(zé)任鏈進(jìn)行設(shè)計(jì)。當(dāng)需要添加一個(gè)處理邏輯時(shí)可以很方便的添加一個(gè)處理的節(jié)點(diǎn)。
現(xiàn)在我們的需求是處理用戶的請求,將用戶提交的字符串信息進(jìn)行層層處理,同時(shí)在處理完成之后返回結(jié)果時(shí),也要對(duì)返回的字符串進(jìn)行層層處理,而處理返回的情況時(shí)其處理的順序和先前是正好相反的順序。
首先建立用戶的請求和接收對(duì)象Request和Response:
- package com.lcq.filter;
 - public class Request {
 - String requestStr;
 - public String getRequestStr() {
 - return requestStr;
 - }
 - public void setRequestStr(String requestStr) {
 - this.requestStr = requestStr;
 - }
 - }
 
- package com.lcq.filter;
 - public class Response {
 - String responseStr;
 - public String getResponseStr() {
 - return responseStr;
 - }
 - public void setResponseStr(String responseStr) {
 - this.responseStr = responseStr;
 - }
 - }
 
我們將處理用戶信息的邏輯抽象成為一個(gè)個(gè)的過濾器,進(jìn)一步抽象出過濾器接口Filter:
- package com.lcq.filter;
 - public interface Filter {
 - public void doFilter(Request request, Response response,FilterChain chain);
 - }
 
注意在Filte接口中doFilter方法參數(shù)中有FilterChain的一個(gè)變量,我們再建立FilterChain類:
- package com.lcq.filter;
 - import java.util.ArrayList;
 - import java.util.List;
 - public class FilterChain implements Filter {
 - List<Filter> filters = new ArrayList<Filter>();
 - int index = 0;
 - public FilterChain addFilter(Filter f) {
 - this.filters.add(f);
 - return this;
 - }
 - @Override
 - public void doFilter(Request request, Response response, FilterChain chain) {
 - if (index == filters.size())
 - return;
 - Filter f = filters.get(index);
 - index++;
 - f.doFilter(request, response, chain);
 - }
 - }
 
在FilterChain中繼承了Filter接口,從而實(shí)現(xiàn)了doFilter方法,在FilterChain中又有一個(gè)index變量,該變量是用來標(biāo)記當(dāng)前訪問的是哪一個(gè)過濾器,這些過濾器是存放在ArrayList中的,這樣用戶在使用的時(shí)候就可以實(shí)現(xiàn)自己的過濾器,編寫自己的處理邏輯,從而將自己的過濾器添加到ArrayList中,再調(diào)用FilterChain的doFilter方法遍歷整個(gè)責(zé)任鏈。
下面我們編寫三個(gè)過濾器:
HTMLFilter類:
- package com.lcq.filter;
 - /**
 - * 過濾HTML中的腳本元素
 - * @author lcq
 - *
 - */
 - public class HTMLFilter implements Filter {
 - @Override
 - public void doFilter(Request request, Response response,FilterChain chain) {
 - request.requestStr = request.getRequestStr().replace("<", "[")
 - .replace(">", "] --------HTMLFilter");
 - chain.doFilter(request, response, chain);
 - response.responseStr += "--------HTMLFilter";
 - }
 - }
 
SesitiveFilter類:
- package com.lcq.filter;
 - public class SesitiveFilter implements Filter {
 - @Override
 - public void doFilter(Request request, Response response, FilterChain chain) {
 - request.requestStr = request.getRequestStr().replace("敏感", " ")
 - .replace("貓貓", "haha------SesitiveFilter");
 - chain.doFilter(request, response, chain);
 - response.responseStr += "------SesitiveFilter";
 - }
 - }
 
FaceFilter類:
- package com.lcq.filter;
 - public class FaceFilter implements Filter {
 - @Override
 - public void doFilter(Request request, Response response, FilterChain chain) {
 - request.requestStr = request.getRequestStr().replace(":)",
 - "^V^-------FaceFilter");
 - chain.doFilter(request, response, chain);
 - response.responseStr += "-------FaceFilter";
 - }
 - }
 
***編寫測試類:
- package com.lcq.filter;
 - public class Main {
 - public static void main(String[] args) {
 - String message = "敏感詞匯,重慶,<script> 躲貓貓 :)";
 - Request request = new Request();
 - request.setRequestStr(message);
 - Response response = new Response();
 - response.setResponseStr("response");
 - FilterChain fc = new FilterChain();
 - fc.addFilter(new HTMLFilter()).addFilter(new SesitiveFilter());
 - FilterChain fc2 = new FilterChain();
 - fc2.addFilter(new FaceFilter());
 - fc.addFilter(fc2);
 - fc.doFilter(request, response,fc);
 - System.out.println("request = " + request.getRequestStr());
 - System.out.println("response = " + response.getResponseStr());
 - }
 - }
 
在上面的實(shí)例中應(yīng)該注意兩個(gè)地方:
1.我們建立的FilterChain中繼承了Filter接口,所以在測試類中就可以像使用其他的過濾器一樣使用FilterChain,大大提高了靈活性;
2.對(duì)于實(shí)現(xiàn)責(zé)任鏈的訪問處理順序問題,該問題的解決使用的是遞歸的思想,從而使先調(diào)用的結(jié)點(diǎn)在處理返回結(jié)果時(shí)其調(diào)用過濾器的順序是相反的。這種解決方案在Struts和其他框架中實(shí)現(xiàn)過濾器和攔截器使用的較為普遍,并且十分巧妙。
原文鏈接:http://blog.csdn.net/liuchangqing123/article/details/7386912
【編輯推薦】















 
 
 










 
 
 
 