创建一个按顺序处理调用的对象链。如果一个对象不能处理调用,它将把调用委托给链中的下一个对象,以此类推。
Handler.php
<?php declare(strict_types=1); namespace DesignPatternsBehavioralChainOfResponsibilities; use PsrHttpMessageRequestInterface; abstract class Handler { public function __construct(private ?Handler $successor = null) { } final public function handle(RequestInterface $request): ?string { $processed = $this->processing($request); if ($processed === null && $this->successor !== null) { // the request has not been processed by this handler => see the next $processed = $this->successor->handle($request); } return $processed; } abstract protected function processing(RequestInterface $request): ?string; }
Responsible/FastStorage.php
<?php declare(strict_types=1); namespace DesignPatternsBehavioralChainOfResponsibilitiesResponsible; use DesignPatternsBehavioralChainOfResponsibilitiesHandler; use PsrHttpMessageRequestInterface; class HttpInMemoryCacheHandler extends Handler { public function __construct(private array $data, ?Handler $successor = null) { parent::__construct($successor); } protected function processing(RequestInterface $request): ?string { $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 declare(strict_types=1); namespace DesignPatternsBehavioralChainOfResponsibilitiesResponsible; use DesignPatternsBehavioralChainOfResponsibilitiesHandler; use PsrHttpMessageRequestInterface; class SlowDatabaseHandler extends Handler { protected function processing(RequestInterface $request): ?string { // this is a mockup, in production code you would ask a slow (compared to in-memory) DB for the results return "Hello World!"; } }
Tests/ChainTest.php
<?php declare(strict_types=1); namespace DesignPatternsBehavioralChainOfResponsibilitiesTests; use DesignPatternsBehavioralChainOfResponsibilitiesHandler; use DesignPatternsBehavioralChainOfResponsibilitiesResponsibleHttpInMemoryCacheHandler; use DesignPatternsBehavioralChainOfResponsibilitiesResponsibleSlowDatabaseHandler; use PHPUnitFrameworkTestCase; use PsrHttpMessageRequestInterface; use PsrHttpMessageUriInterface; class ChainTest extends TestCase { private Handler $chain; protected function setUp(): void { $this->chain = new HttpInMemoryCacheHandler( ["/foo/bar?index=1" => "Hello In Memory!"], new SlowDatabaseHandler() ); } public function testCanRequestKeyInFastStorage() { $uri = $this->createMock(UriInterface::class); $uri->method("getPath")->willReturn("/foo/bar"); $uri->method("getQuery")->willReturn("index=1"); $request = $this->createMock(RequestInterface::class); $request->method("getMethod") ->willReturn("GET"); $request->method("getUri")->willReturn($uri); $this->assertSame("Hello In Memory!", $this->chain->handle($request)); } public function testCanRequestKeyInSlowStorage() { $uri = $this->createMock(UriInterface::class); $uri->method("getPath")->willReturn("/foo/baz"); $uri->method("getQuery")->willReturn(""); $request = $this->createMock(RequestInterface::class); $request->method("getMethod") ->willReturn("GET"); $request->method("getUri")->willReturn($uri); $this->assertSame("Hello World!", $this->chain->handle($request)); } }
UML 概述:UML是 OMG 在1997年1月提出了创建由对象管理组和 UML1.0 规范草案;UML 是一种为面向对象开发系统的产品进行说明、可视...
测试用例是一组条件,测试人员根据这些条件确定软件应用程序是否按照客户的要求工作。测试用例设计包括前提条件,用例名称,输入...
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的...
在空对象模式(Null Object Pattern)中,一个空对象取代 NULL 对象实例的检查。Null 对象不是检查空值,而是反应一个不做任何动...
软件测试是根据从用户和系统规范收集的需求对软件进行评估。测试在软件开发生命周期的阶段级别或程序代码的模块级别进行。软件测...