sroze/责任链模式

一个轻量级的库,简化了责任链模式的实现

1.2.1 2017-03-01 16:22 UTC

This package is auto-updated.

Last update: 2024-09-16 12:45:39 UTC


README

Build Status SensioLabsInsight Scrutinizer Code Quality Code Coverage

这个轻量级库可以帮助快速实现责任链模式。当需要涉及多个步骤的清晰流程时,此模式特别有用。

安装

建议的安装方法是使用 composer

composer require sroze/chain-of-responsibility

用法

有两个组件

  • 运行器:它将接收一系列过程,将它们装饰为责任链并执行头部。
  • 构建器:它会给过程添加一些功能,因为它们可以声明一个需要在之前运行的其他过程的列表。

运行器

创建实现 ChainProcessInterface 接口的过程类。此接口只有一个 execute 方法,它接受一个 ChainContext 对象作为参数。此参数可用作数组,并为您的过程提供交换信息的一种通用方式。

use SRIO\ChainOfResponsibility\ChainContext;
use SRIO\ChainOfResponsibility\ChainProcessInterface;

class LambdaProcess implements ChainProcessInterface
{
    /**
     * {@inheritdoc}
     */
    public function execute(ChainContext $context)
    {
        // Do whatever you want in this small process, such as
        // sending a mail, manipulating files, ...
    }
}

使用给定过程列表创建链运行器。列表顺序非常重要,因为它将是过程的执行顺序。

$runner = new ChainRunner([
    new FirstProcess(),
    new SecondProcess(),
    new ThirdProcess()
]);

然后,使用 run 方法运行每个过程,可以带有一个 可选的 ChainContext 参数。

$runner->run(new ArrayChainContext([
    'foo' => 'bar'
]));

构建器

构建器可以根据过程之间的依赖关系构建您的责任链。为了声明依赖关系,您的过程必须实现 DependentChainProcessInterface 接口。

use SRIO\ChainOfResponsibility\ChainContext;
use SRIO\ChainOfResponsibility\DependentChainProcessInterface;

class FooProcess implements DependentChainProcessInterface
{
    /**
     * {@inheritdoc}
     */
    public function execute(ChainContext $context)
    {
        // Do whatever you want...
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'foo';
    }

    /**
     * {@inheritdoc}
     */
    public function dependsOn()
    {
        return ['bar'];
    }
}

然后,创建另一个 BarProcess,其 getName 方法将返回 bar,其 dependsOn 将返回一个空数组。

通过创建一个实例并将其传递实现至少 ChainProcessInterface 的过程数组来创建一个 ChainBuilder。与 ChainRunner 一样,您也可以调用 add 方法添加一个或多个过程。

$builder = new ChainBuilder([
    new FooProcess(),
    new BarProcess(),
]);

现在,您可以通过调用 getRunner 方法检索链运行器。

$runner = $builder->getRunner();
$runner->run();

在给定的上一个示例中,bar 过程将在 foo 过程之前执行。

高级

使用自定义过程装饰器

为了创建链,ChainBuilder 使用 ChainProcessDecorator 类装饰您的过程。如果您想使用自己的装饰器添加额外的逻辑,如错误恢复或记录,您可以很容易地通过提供一个实现 DecoratorFactoryInterface 的对象来覆盖装饰器。

$decoratorFactory = new DecoratorFactory();
$runner = new ChainRunner([], $decoratorFactory);