天天看點

PHP設計模式—職責鍊模式

定義:

職責鍊模式(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對象負責處理它。
  • 職責鍊模式中接收者和發送者都沒有對方的明确資訊,且鍊中的對象自己也并不知道鍊的結構。是以職責鍊可簡化對象的互相連接配接,它們僅需保持一個指向其後繼者的引用,而不需要保持它所有的候選接受者的引用,這大大降低了耦合度。
  • 由于是在用戶端來定義鍊的結構,可以随時地增加或修改處理一個請求的結構,增強了給對象指派職責的靈活性。
  • 需要注意的是,一個請求極有可能到了鍊的末端都得不到處理,或者因為沒有正确配置而得不到處理,是以需要事先考慮全面。