PHP-責任鏈模式

lemon_lyue發表於2020-07-22

什麼是責任鏈模式

責任鏈模式(Chain Of Responisibility):使多個物件都有機會處理請求,從而避免請求的傳送者和接收者之間的耦合關係。將這個物件連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個物件處理它為止。

責任鏈模式的實現

這裡用責任鏈模式寫一箇中介軟體來做示範,先新建一個抽象中介軟體處理類

Middleware\MiddlewareHandler.php

<?php
namespace Middleware;

/**
 * Class MiddlewareHandler
 * @package Middleware
 */
abstract class MiddlewareHandler
{
    // 下一個處理者
    private $nextHandler;

    /**
     * @desc 處理方法
     * @return mixed
     */
    abstract protected function handler();

    /**
     * @desc 設定下一個處理者
     * @param MiddlewareHandler $handler
     * @return $this
     */
    public function setNextHandler(MiddlewareHandler $handler)
    {
        $this->nextHandler = $handler;
        return $this;
    }

    /**
     * @desc 責任鏈實現方法
     */
    final public function handlerMessage()
    {
        $this->handler();
        if (!empty($this->nextHandler)) {
            $this->nextHandler->handlerMessage();
        }
    }
}

寫好了抽象類之後就可以實現具體的中介軟體類去繼承該抽象類了。中介軟體一般去校驗簽名校驗jwt登入等等。

Middleware\CheckSign.php

<?php
namespace Middleware;
class CheckSign extends MiddlewareHandler
{
    protected function handler()
    {
        echo 'check sign...'.PHP_EOL;
    }
}

Middleware\CheckJwt.php

<?php
namespace Middleware;
class CheckJwt extends MiddlewareHandler
{
    protected function handler()
    {
        echo 'check jwt...'.PHP_EOL;
    }
}

中介軟體已經實現完成了,萬事俱備只欠呼叫

這裡實現一個index.php,這裡使用了兩種方式去呼叫,一種是手動去構建責任鏈去呼叫,另外一種是將需要構建的責任鏈存於陣列,程式去構建責任鏈

index.php

<?php
use Middleware\RegisterMiddleware;
spl_autoload_register(function($class_name) {
    require_once str_replace('\\','/',$class_name).'.php';
});

/**
 * @desc 自動例項化構建責任鏈
 */
new RegisterMiddleware();

/**
 * @desc 手動構建
 */
use Middleware\CheckJwt;
use Middleware\CheckSign;

$checkJwt  = new CheckJwt();
$checkSign = new CheckSign();
$checkSign->setNextHandler($checkJwt);
$checkSign->handlerMessage();

程式構建責任鏈程式碼如下

Middleware\RegisterMiddleware.php

<?php
namespace Middleware;
class RegisterMiddleware
{
    /**
     * @desc 配置中介軟體,責任順序與陣列內順序一致
     * @var array
     */
    protected $middlewareArr = [

        CheckSign::class,

        CheckJwt::class,

    ];

    protected $handler;
    protected $middleware;

    /**
     * @desc 構造方法自動構建責任鏈
     * RegisterMiddleware constructor.
     */
    public function __construct()
    {
        foreach ($this->middlewareArr as $key => $item) {
            $next = isset($this->middlewareArr[$key + 1]) ? $this->middlewareArr[$key + 1] : null;
            if ($key === 0) {
                $this->handler = new $item();
                if (!empty($next)) {
                    $this->middleware = new $next();
                    $this->handler->setNextHandler($this->middleware);
                }
            } elseif (!empty($next)) {
                $mid = new $next();
                $this->middleware->setNextHandler($mid);
            }
        }
        $this->handler->handlerMessage();
    }
}

責任鏈模式應用場景

責任鏈模式主要可以去實現過濾器攔截器、中介軟體和工作流等

本作品採用《CC 協議》,轉載必須註明作者和本文連結

lemon_lyue

相關文章