举报投诉联系我们 手机版 热门标签 名动网
您的位置:名动网 > php责任链模式为什么不直接处理 PHP 责任链模式

php责任链模式为什么不直接处理 PHP 责任链模式

2023-06-09 00:20 PHP设计模式

php责任链模式为什么不直接处理 PHP 责任链模式

php责任链模式为什么不直接处理 PHP 责任链模式

php责任链模式为什么不直接处理

目的

创建一个按顺序处理调用的对象链。如果一个对象不能处理调用,它将把调用委托给链中的下一个对象,以此类推。

例子

  • 日志框架,其中每个链元素自主决定如何处理日志信息
  • 垃圾邮件过滤器
  • 缓存:第一个对象是一个例如Memcached的接口,如果“没有命中”它则委托调用数据库的接口

UML 图

Alt ChainOfResponsibility UML Diagram

代码

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));
    }
}
阅读全文
以上是名动网为你收集整理的php责任链模式为什么不直接处理 PHP 责任链模式全部内容。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。
相关文章
© 2024 名动网 mdwl.vip 版权所有 联系我们