定義
避免請求傳送者與接收者耦合在一起,讓多個物件都有可能接收請求,將這些物件連線成一條鏈,並且沿著這條鏈傳遞請求,直到有物件處理它為止。
設計的原則和思想
- 解耦的是請求傳送物件(觸發業務的物件)和請求處理物件(處理業務的物件)。
- 不變部分是請求處理物件,變化部分是請求處理物件之間的關係。
- 核心思想是 將請求處理物件之間的關係,從一對多的關係,轉化成鏈型關係。
一句話概括設計模式
多個處理者連線成一條鏈,並且各自承擔各自的處理職責。
結構中包含的角色
- Handler(抽象處理者)
- ConcreteHandler(具體處理者)
最小可表達程式碼
abstract class Handler
{
protected $nextHandler;
public function setNextHandler(Handler $nextHandler)
{
$this->nextHandler = $nextHandler;
}
public abstract function handleRequest(String $request);
}
class ConcreteHandler extends Handler
{
public function handleRequest(String $request)
{
$isForward = false;
if (! $isForward) {
var_dump('業務處理' . $request);
$isForward = true;
}
if ($isForward && $this->nextHandler) {
$this->nextHandler->handleRequest($request);
}
}
}
$request = 'test';
$handler1 = new ConcreteHandler();
$handler2 = new ConcreteHandler();
$handler1->setNextHandler($handler2);
$handler1->handleRequest($request);
優點
- 一個物件無須知道是其他哪一個物件處理其請求,物件僅需知道該請求會被處理即可。
- 把請求處理物件之間的關係,從一對多的關係,轉化成一對一的關係。簡化了物件之間的相互連線的關係。
- 你可以控制請求處理的順序。
- 增加新的請求處理類很方便。
缺點
- 不能保證請求一定被處理。
- 長的職責鏈,效能會有一定影響,除錯程式碼也不太方便。
- 建鏈程式碼複雜。
何時使用
- 多個物件處理同一個請求。
- 需要使用不同方式處理不同請求。
- 需要按順序執行多個處理者時。
- 需要處理者及其順序必須在執行時進行改變。
實際應用場景
- 過濾這些敏感詞。
- JS 中的事件冒泡。
- 工作流中的分級審批。
純的職責鏈模式和不純的職責鏈模式
純的職責鏈模式
要麼承擔全部責任,要麼將責任推給下家,不允許出現某一個具體處理者物件在承擔了一部分或全部責任後又將責任向下傳遞的情況。
而且在純的職責鏈模式中,要求一個請求必須被某一個處理者物件所接收,不能出現某個請求未被任何一個處理者物件處理的情況。
不純的職責鏈模式
在一個不純的職責鏈模式中允許某個請求被一個具體處理者部分處理後再向下傳遞,或者一個具體處理者處理完某請求後其後繼處理者可以繼續處理該請求,而且一個請求可以最終不被任何處理者物件所接收。
本作品採用《CC 協議》,轉載必須註明作者和本文連結