定義:
職責鍊模式(Chain of Responsibility):使多個對象都有機會處理請求,進而避免請求的發送者和接收者之間的耦合關系。将這個對象連成一條鍊,并沿着這條鍊傳遞該請求,直到有一個對象處理它為止。
結構:
- Handler:抽象類,定義一個處理請示的接口。
- ConcreteHandler:具體處理者類,處理它所負責的請求,可通路它的後繼者,如果可以處理該請求,就處理之,否則就将請求轉發給它的後繼者。
- Client:用戶端代碼。
代碼執行個體:
/**
* 抽象類,定義一個處理請示的接口
* Class Handler
*/
abstract class Handler
{
/**
* 存放下一個處理對象
* @var
*/
protected $nextHandler;
/**
* 設定下一個處理對象
* @param Handler $handler
*/
public function setNextHandler(Handler $handler)
{
$this->nextHandler = $handler;
}
/**
* 抽象方法,由具體處理者類實作
* @param $request
* @return mixed
*/
abstract public function handlerRequest($request);
}
/**
* 具體處理者類
* Class ConcreteHandler1
*/
class ConcreteHandler1 extends Handler
{
/**
* 具體處理邏輯
* @param $request
* @return mixed|void
*/
public function handlerRequest($request)
{
// TODO: Implement handlerRequest() method.
if ($request >= 0 && $request < 10) {
// ConcreteHandler1可以處理0~10的請求
echo 'ConcreteHandler1處理這個請求<br>';
} elseif ($this->nextHandler) {
// 請求轉發給下一個處理對象
$this->nextHandler->handlerRequest($request);
} else {
echo 'ConcreteHandler1處理異常<br>';
}
}
}
/**
* 具體處理者類
* Class ConcreteHandler2
*/
class ConcreteHandler2 extends Handler
{
/**
* 具體處理邏輯
* @param $request
* @return mixed|void
*/
public function handlerRequest($request)
{
// TODO: Implement handlerRequest() method.
if ($request >= 10 && $request < 20) {
// ConcreteHandler2可以處理10~20的請求
echo 'ConcreteHandler2處理這個請求<br>';
} elseif ($this->nextHandler) {
// 請求轉發給下一個處理對象
$this->nextHandler->handlerRequest($request);
} else {
echo 'ConcreteHandler2處理異常<br>';
}
}
}
/**
* 具體處理者類
* Class ConcreteHandler3
*/
class ConcreteHandler3 extends Handler
{
/**
* 具體處理邏輯
* @param $request
* @return mixed|void
*/
public function handlerRequest($request)
{
// TODO: Implement handlerRequest() method.
if ($request >= 20) {
// ConcreteHandler3可以處理大于20的請求
echo 'ConcreteHandler3處理這個請求<br>';
} elseif ($this->nextHandler) {
// 請求轉發給下一個處理對象
$this->nextHandler->handlerRequest($request);
} else {
echo 'ConcreteHandler3處理異常<br>';
}
}
}
// 用戶端代碼
// 執行個體化處理者
$handler1 = new ConcreteHandler1();
$handler2 = new ConcreteHandler2();
$handler3 = new ConcreteHandler3();
// 職責鍊組裝,定義鍊的結構,設定職責鍊上家與下家
$handler1->setNextHandler($handler2);
$handler2->setNextHandler($handler3);
// 調用請求
$handler1->handlerRequest(5);
$handler1->handlerRequest(15);
$handler1->handlerRequest(35);
// 結果
ConcreteHandler1處理這個請求
ConcreteHandler2處理這個請求
ConcreteHandler3處理這個請求
總結:
- 當客戶送出一個請求時,請求是沿鍊傳遞直至有一個ConcreteHandler對象負責處理它。
- 職責鍊模式中接收者和發送者都沒有對方的明确資訊,且鍊中的對象自己也并不知道鍊的結構。是以職責鍊可簡化對象的互相連接配接,它們僅需保持一個指向其後繼者的引用,而不需要保持它所有的候選接受者的引用,這大大降低了耦合度。
- 由于是在用戶端來定義鍊的結構,可以随時地增加或修改處理一個請求的結構,增強了給對象指派職責的靈活性。
- 需要注意的是,一個請求極有可能到了鍊的末端都得不到處理,或者因為沒有正确配置而得不到處理,是以需要事先考慮全面。