1. 責任鏈模式定義
責任鏈模式是一種對象的行爲模式。在責任鏈模式裏,很多對象由每一個對象對其下家的引用而連接起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。發出這個請求的客戶端並不知道鏈上的哪一個對象最終處理這個請求,這使得系統可以在不影響客戶端的情況下動態地重新組織和分配責任。Tomcat中的Filter就是使用了責任鏈模式,創建一個Filter除了要在web.xml文件中做相應配置外,還需要實現javax.servlet.Filter接口。
2. 具體實例
我們有一個字符串String msg = ":):,<script>
,敏感,被就業,網絡授課";我們希望應用以下三個規則對字符串進行過濾和諧處理:
- 將字符串中出現的"<>“符號替換成”[]"
- 處理字符串中的敏感信息,將被就業和諧成就業
- 將字符串中出現的
":):"
轉換成"^V^"
字符串會依次運用這三條規則,對字符串進行處理,每個規則都有自己需要完成的責任和任務。
第一步:定義封裝請求的類Request和封裝處理結果響應的類Response
//封裝請求的類Request
public class Request {
String requestStr;
public String getRequest() {
return requestStr;
}
public void setRequest(String request) {
this.requestStr = request;
}
}
//封裝響應信息的類Response
public class Response {
String responseStr;
public String getResponse() {
return responseStr;
}
public void setResponse(String response) {
this.responseStr = response;
}
}
第二步:定義具有過濾功能的接口Filter,具體的過濾規則需要實現該接口
/*
* 定義接口Filter,具體的過濾規則需要實現這個接口,最後一個參數添加的意義是我們在Main函數中:
* fc.doFilter(request, response,fc);執行這一步的時候可以按照規則鏈條一次使用三個過濾規則對字符串進行處理
* 因爲
*
*/
public interface Filter {
void doFilter(Request request,Response response,FilterChain chain);
}
第三步:定義具體的過濾處理規則
規則一
package com.bjsxt.dp.filter;
//處理字符串中的HTML標記
public class HTMLFilter implements Filter {
public void doFilter(Request request, Response response,FilterChain chain) {
//將字符串中出現的"<>"符號替換成"[]"
request.requestStr=request.requestStr
.replace('<', '[').replace('>', ']')+
//後面添加的是便於我們觀察代碼執行步驟的字符串
"----HTMLFilter()";
chain.doFilter(request, response,chain);
response.responseStr+="---HTMLFilter()";
}
}
規則二
package com.bjsxt.dp.filter;
//定義的過濾敏感字眼的過濾規則
public class SensitiveFilter implements Filter{
public void doFilter(Request request, Response response,FilterChain chain) {
//處理字符串中的敏感信息,將被就業和諧成就業
request.requestStr=request.requestStr
.replace("被就業", "就業").replace("敏感", "")+
//後面添加的是便於我們觀察代碼執行步驟的字符串
" ---sensitiveFilter()";
chain.doFilter(request, response,chain);
response.responseStr+="---sensitiveFilter()";
}
}
規則三
package com.bjsxt.dp.filter;
//定義FaceFilter
public class FaceFilter implements Filter {
public void doFilter(Request request, Response response, FilterChain chain) {
//將字符串中出現的":):"轉換成"^V^";
request.requestStr = request.requestStr.replace(":):", "^V^")
//後面添加的是便於我們觀察代碼執行步驟的字符串
+ "----FaceFilter()";
chain.doFilter(request, response, chain);
response.responseStr += "---FaceFilter()";
}
}
第四步:定義責任鏈FilterChain
package com.bjsxt.dp.filter;
import java.util.ArrayList;
import java.util.List;
//過濾鏈條
public class FilterChain implements Filter{
//用List集合來存儲過濾規則
List<Filter> filters = new ArrayList<Filter>();
//用於標記規則的引用順序
int index=0;
//往規則鏈條中添加規則
public FilterChain addFilter(Filter f) {
filters.add(f);
//代碼的設計技巧:Chain鏈添加過濾規則結束後返回添加後的Chain,方便我們下面doFilter函數的操作
return this;
}
public void doFilter(Request request,Response response,FilterChain chain){
//index初始化爲0,filters.size()爲3,不會執行return操作
if(index==filters.size()){
return;
}
//每添加一個過濾規則,index自增1
Filter f=filters.get(index);
index++;
//根據索引值獲取對應的規律規則對字符串進行處理
f.doFilter(request, response, chain);
}
}
第五步:測試一下我們的代碼
package com.bjsxt.dp.filter;
/*
* 責任鏈模式:
* 數據消息在進入數據庫之前,要被多種過濾規則進行處理,多種規則形成一種鏈,依次處理
* 給定的數據消息
*/
public class Main {
public static void main(String args[]) {
//設定過濾規則,對msg字符串進行過濾處理
String msg = ":):,<script>,敏感,被就業,網絡授課";
//過濾請求
Request request=new Request();
//set方法,將待處理字符串傳遞進去
request.setRequest(msg);
//處理過程結束,給出的響應
Response response=new Response();
//設置響應信息
response.setResponse("response:");
//FilterChain,過濾規則形成的攔截鏈條
FilterChain fc=new FilterChain();
//規則鏈條添加過濾規則,採用的是鏈式調用
fc.addFilter(new HTMLFilter())
.addFilter(new SensitiveFilter())
.addFilter(new FaceFilter());
//按照FilterChain的規則順序,依次應用過濾規則
fc.doFilter(request, response,fc);
//打印請求信息
System.out.println(request.getRequest());
//打印響應信息
System.out.println(response.getResponse());
/*
* 處理器對數據進行處理
* --|----|---數據--|-----|---
* 規則1 規則2 規則3 規則4
*/
}
}
運行結果:
^V^,[script],,就業,網絡授課----HTMLFilter() ---sensitiveFilter()----FaceFilter()
response:---FaceFilter()---sensitiveFilter()---HTMLFilter()
運行過程如下:
3. 責任鏈模式的好處
過濾鏈的好處是,發出請求的客戶端並不知道鏈上的哪一個過濾器將處理這個請求,這使得系統可以在不影響客戶端的情況下 動態地重新組織鏈和分配責任,並且在執行過程中的任何時候都可以打斷,只要不執行chain.doFilter()就不會再執行後面的過濾器和請求的內容,這顯然可以看作是 非純責任鏈模式 的一種典型實現。
參考: