目的
建立一個物件鏈來按指定順序處理呼叫,如果其中一個物件無法處理命令,它會委托這個呼叫給它的下一個物件來進行處理,以此類推,
例子
-
垃圾郵件過濾器,
-
日志框架,每個鏈元素自主決定如何處理日志訊息,
-
快取:例如第一個物件是一個 Memcached 介面實體,如果 “丟失” 它會委托資料庫介面處理這個呼叫,
-
Yii 框架: CFilterChain 是一個控制器行為過濾器鏈,執行點會有鏈上的過濾器逐個傳遞,并且只有當所有的過濾器驗證通過,這個行為最后才會被呼叫,
UML 圖

★官方PHP高級學習交流社群「點擊」管理整理了一些資料,BAT等一線大廠進階知識體系備好(相關學習資料以及筆面試題)以及不限于:分布式架構、高可擴展、高性能、高并發、服務器性能調優、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優化、shell腳本、Docker、微服務、Nginx等多個知識點高級進階干貨
代碼
- Handler.php
<?php
namespace DesignPatterns\Behavioral\ChainOfResponsibilities;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
/**
* 創建處理器抽象類 Handler ,
*/
abstract class Handler
{
/**
* @var Handler|null
* 定義繼承處理器
*/
private $successor = null;
/**
* 輸入集成處理器物件,
*/
public function __construct(Handler $handler = null)
{
$this->successor = $handler;
}
/**
* 通過使用模板方法模式這種方法可以確保每個子類不會忽略呼叫繼
* 承,
*
* @param RequestInterface $request
* 定義處理請求方法,
*
* @return string|null
*/
final public function handle(RequestInterface $request)
{
$processed = $this->processing($request);
if ($processed === null) {
// 請求尚未被目前的處理器處理 => 傳遞到下一個處理器,
if ($this->successor !== null) {
$processed = $this->successor->handle($request);
}
}
return $processed;
}
/**
* 宣告處理方法,
*/
abstract protected function processing(RequestInterface $request);
}
- Responsible/FastStorage.php
<?php
namespace DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible;
use DesignPatterns\Behavioral\ChainOfResponsibilities\Handler;
use Psr\Http\Message\RequestInterface;
/**
* 創建 http 快取處理類,
*/
class HttpInMemoryCacheHandler extends Handler
{
/**
* @var array
*/
private $data;
/**
* @param array $data
* 傳入資料陣列引數,
* @param Handler|null $successor
* 傳入處理器類物件 $successor ,
*/
public function __construct(array $data, Handler $successor = null)
{
parent::__construct($successor);
$this->data = https://www.cnblogs.com/phpyu/p/$data;
}
/**
* @param RequestInterface $request
* 傳入請求類物件引數 $request ,
* @return string|null
*
* 回傳快取中對應路徑存盤的資料,
*/
protected function processing(RequestInterface $request)
{
$key = sprintf('%s?%s',
$request->getUri()->getPath(),
$request->getUri()->getQuery()
);
if ($request->getMethod() == 'GET' && isset($this->data[$key])) {
return $this->data[$key];
}
return null;
}
}
- Responsible/SlowStorage.php
<?php
namespace DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible;
use DesignPatterns\Behavioral\ChainOfResponsibilities\Handler;
use Psr\Http\Message\RequestInterface;
/**
* 創建資料庫處理器,
*/
class SlowDatabaseHandler extends Handler
{
/**
* @param RequestInterface $request
* 傳入請求類物件 $request ,
*
* @return string|null
* 定義處理方法,下面應該是個資料庫查詢動作,但是簡單化模擬,直接回傳一個 'Hello World' 字串作查詢結果,
*/
protected function processing(RequestInterface $request)
{
// 這是一個模擬輸出, 在生產代碼中你應該呼叫一個緩慢的 (相對于記憶體來說) 資料庫查詢結果,
return 'Hello World!';
}
}
測驗
- Tests/ChainTest.php
<?php
namespace DesignPatterns\Behavioral\ChainOfResponsibilities\Tests;
use DesignPatterns\Behavioral\ChainOfResponsibilities\Handler;
use DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible\HttpInMemoryCacheHandler;
use DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible\SlowDatabaseHandler;
use PHPUnit\Framework\TestCase;
/**
* 創建一個自動化測驗單元 ChainTest ,
*/
class ChainTest extends TestCase
{
/**
* @var Handler
*/
private $chain;
/**
* 模擬設定快取處理器的快取資料,
*/
protected function setUp()
{
$this->chain = new HttpInMemoryCacheHandler(
['/foo/bar?index=1' => 'Hello In Memory!'],
new SlowDatabaseHandler()
);
}
/**
* 模擬從快取中拉取資料,
*/
public function testCanRequestKeyInFastStorage()
{
$uri = $this->createMock('Psr\Http\Message\UriInterface');
$uri->method('getPath')->willReturn('/foo/bar');
$uri->method('getQuery')->willReturn('index=1');
$request = $this->createMock('Psr\Http\Message\RequestInterface');
$request->method('getMethod')
->willReturn('GET');
$request->method('getUri')->willReturn($uri);
$this->assertEquals('Hello In Memory!', $this->chain->handle($request));
}
/**
* 模擬從資料庫中拉取資料,
*/
public function testCanRequestKeyInSlowStorage()
{
$uri = $this->createMock('Psr\Http\Message\UriInterface');
$uri->method('getPath')->willReturn('/foo/baz');
$uri->method('getQuery')->willReturn('');
$request = $this->createMock('Psr\Http\Message\RequestInterface');
$request->method('getMethod')
->willReturn('GET');
$request->method('getUri')->willReturn($uri);
$this->assertEquals('Hello World!', $this->chain->handle($request));
}
}
PHP 互聯網架構師成長之路*「設計模式」終極指南
PHP 互聯網架構師 50K 成長指南+行業問題解決總綱(持續更新)
面試10家公司,識訓9個offer,2020年PHP 面試問題
★如果喜歡我的文章,想與更多資深開發者一起交流學習的話,獲取更多大廠面試相關技術咨詢和指導,歡迎加入我們的群啊,暗號:phpzh(君羊號碼856460874),
2020年最新PHP進階教程,全系列!

內容不錯的話希望大家支持鼓勵下點個贊/喜歡,歡迎一起來交流;另外如果有什么問題 建議 想看的內容可以在評論提出
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/70482.html
標籤:PHP
上一篇:重賞!求一個游樂場管理系統原始碼
