算是讀書筆記吧
極客時間--設計模式之美
什麼是職責鏈模式
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
將請求的發送和接收解耦,讓多個接收對象都有機會處理這個請求。將這些接收對象串成一條鏈,並沿着這條鏈傳遞這個請求,直到鏈上的某個接收對象能夠處理它爲止
舉一個形象的例子,每一層都會過濾掉不同的雜質
對應到代碼中,可以看做是在發現某條信息中含有違規信息,就終止當條信息繼續傳遞。
而職責鏈,就是講這一層一層的篩選,交給一個一個處理器對象進行處理。
職責鏈模式如何實現
如果不使用職責鏈模式
正常情況下,我們會這樣設計
public class SensitiveWordFilter {
// return true if content doesn't contain sensitive words.
public boolean filter(Content content) {
if (!filterSexyWord(content)) {
return false;
}
if (!filterAdsWord(content)) {
return false;
}
if (!filterPoliticalWord(content)) {
return false;
}
return true;
}
private boolean filterSexyWord(Content content) {
//....
}
private boolean filterAdsWord(Content content) {
//...
}
private boolean filterPoliticalWord(Content content) {
//...
}
}
其實很多時候我們都是這樣做的,因爲這些需求經常會變化。
但是如果要設計一個穩定的框架,我們當然不希望所有邏輯都耦合在這一個方法,甚至文件裏。
業務方想要更改一個判斷,要修改框架類。這明顯違背了開閉原則。
用鏈表方式實現職責鏈
通過當前處理器對象調用next,來實現鏈式調用
每個處理器就是一個節點
public abstract class Handler {
protected Handler nextHandler = null;
public void setSuccessor(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract void handle();
}
public class HandlerA extends Handler {
@Override
public boolean handle() {
boolean handled = false;
//...
if (!handled && nextHandler != null) {
nextHandler.handle();
}
}
}
對外使用時,總鏈對象通過激活頭結點,開始處理
public class HandlerChain {
private Handler head = null;
private Handler tail = null;
public void addHandler(Handler handler) {
handler.setSuccessor(null);
if (head == null) {
head = handler;
tail = handler;
return;
}
tail.setSuccessor(handler);
tail = handler;
}
public void handle() {
if (head != null) {
head.handle();
}
}
}
// 使用舉例
public class Application {
public static void main(String[] args) {
HandlerChain chain = new HandlerChain();
chain.addHandler(new HandlerA());
chain.addHandler(new HandlerB());
chain.handle();
}
}
當然,也可以通過在模板方法裏調用next,簡化編碼流程
public abstract class Handler {
protected Handler nextHandler = null;
public void setSuccessor(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public final void handle() {
doHandle();
if (successor != null) {
nextHandler.handle();
}
}
protected abstract void doHandle();
}
public class HandlerA extends Handler {
@Override
protected void doHandle() {
//...
}
}
用數組方式實現職責鏈
將處理器對象存儲在主鏈的數組容器中,由主鏈對象依次調用節點
public class SensitiveWordFilterChain {
private List<SensitiveWordFilter> filters = new ArrayList<>();
public void addFilter(SensitiveWordFilter filter) {
this.filters.add(filter);
}
// return true if content doesn't contain sensitive words.
public boolean filter(Content content) {
for (SensitiveWordFilter filter : filters) {
if (!filter.doFilter(content)) {
return false;
}
}
return true;
}
}
職責鏈模式的變體
經典的職責鏈模式
一旦某個處理器能處理這個請求,就不會繼續將請求傳遞給後續的處理器了
職責鏈模式的變體
請求不會中途終止傳遞,而是會被所有的處理器都處理一遍。