設計模式學習(十六):責任鏈模式
設計模式學習(十六):責任鏈模式
作者:Grey
原文地址:
責任鏈模式
責任鏈模式是一種行為型模式。
舉例說明:有一段文本需要過濾一系列敏感字,我們可以通過責任鏈模式來設計這個功能,假設文本是
scripts Hell World! 996
我們有多個過濾規則,比如第一個規則是:過濾 scripts 這個關鍵字(實際的規則可能很複雜,目前只是舉這個簡單例子來說明情況)
第二個規則是:過濾 996 這個關鍵字
首先,將這個文本封裝成一個 Msg 類,文本內容存在 content 變數中
public class Msg {
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
然後,可以抽象一個 Filter 介面,各種過濾規則無非就是實現這個介面即可
public interface Filter {
boolean doFilter(Msg msg);
}
過濾掉 996 這個關鍵字的規則:
public class SensitiveFilter implements Filter {
@Override
public boolean doFilter(Msg msg) {
msg.setContent(msg.getContent().replace("996", ""));
return true;
}
}
過濾 scripts 的規則:
public class HTMLFilter implements Filter {
@Override
public boolean doFilter(Msg msg) {
msg.setContent(msg.getContent().replace("scripts", ""));
return true;
}
}
主方法調用的時候,就直接 New 相應的 Filter 來處理即可:
Msg msg=new Msg();
msg.setContent("scripts Hell World! 996");
System.out.println("before filter , the content is : "+msg.getContent());
Filter html=new HTMLFilter();
Filter sensitive=new SensitiveFilter();
html.doFilter(msg);
sensitive.doFilter(msg);
System.out.println("after filter , the content is : "+msg.getContent());
不過,更為優雅的一種方式是設計一個 FilterChain ,把所有的 Filter 都加入到這個 FilterChain 裡面,對於 Msg 直接去調用 FilterChain 的過濾方法即可把 FilterChain 中的所有 Filter 都執行,而且還可以很靈活指定 Filter 順序。
import java.util.*;
public class FilterChain implements Filter {
private List<Filter> filters = new ArrayList<>();
public FilterChain addFilter(Filter filter) {
filters.add(filter);
return this;
}
@Override
public boolean doFilter(Msg msg) {
for (Filter filter : filters) {
if (!filter.doFilter(msg)) {
return false;
}
}
return true;
}
}
那麼主方法在調用的時候,可以直接通過如下的方式:
public class Main {
public static void main(String[] args) {
FilterChain filterChain = new FilterChain();
filterChain.addFilter(new HTMLFilter()).addFilter(new SensitiveFilter());
Msg msg = new Msg();
msg.setContent("scripts Hell World! 996");
System.out.println("before filter , the content is : " + msg.getContent());
filterChain.doFilter(msg);
System.out.println("after filter , the content is : " + msg.getContent());
}
}
上述示例的 UML 圖如下
責任鏈模式應用
-
Java 中的 Servlet filter;
-
Structs,Spring MVC 中的 interceptor;
-
Dubbo 中的 Filter;
-
Netty 中的 ChannelPipeline。