syberisle/pipeline

1.0.1 2020-10-16 03:38 UTC

This package is auto-updated.

Last update: 2024-09-16 20:01:54 UTC


README

此包提供了一个管道模式的实现。

管道模式

管道模式允许您通过链式连接阶段来轻松组合顺序阶段。

在此特定实现中,接口由两部分组成

  • 管道
  • 处理器
  • 阶段

一个管道可以由零个、一个或多个阶段组成。处理器可以对负载执行管道处理。在处理过程中,负载将被传递到第一个阶段。从那时起,结果值将从阶段传递到阶段。

在最简单的形式中,执行链可以表示为foreach

$result = $payload;

foreach ($stages as $stage) {
    $result = $stage($result);
}

return $result;

实际上,这与以下内容相同

$result = $stage3($stage2($stage1($payload)));

不可变性

管道作为不可变阶段链实现。当您添加新阶段时,将创建一个新的管道,其中包含添加的阶段。这使得管道易于重用,并最小化了副作用。

用法

管道中的操作,即阶段,可以是满足callable类型提示的任何内容,也可以是Stage或Pipeline接口。因此,闭包和任何可调用内容都是可以的。

$pipeline = (new Pipeline\Simple)->pipe(function ($payload) {
    return $payload * 10;
});

基于类的阶段。

基于类的阶段也是可能的。可以实现Stage,以确保您具有正确的process方法签名。

use SyberIsle\Pipeline\Pipeline;
use SyberIsle\Pipeline\Processor;
use SyberIsle\Pipeline\Stage;

class TimesTwoStage implements Stage
{
    public function process($payload)
    {
        return $payload * 2;
    }
}

class AddOneStage implements Stage
{
    public function process($payload)
    {
        return $payload + 1;
    }
}

$pipeline = (new Pipeline\Simple)
    ->pipe(new TimesTwoStage)
    ->pipe(new AddOneStage);

// Returns 21
(new Processor\FingersCrossed())->process($pipeline, 10);

可重用管道

因为PipelineInterface是StageInterface的扩展,所以管道可以作为阶段重用。这创建了一个高度可组合的模型,可以创建复杂的执行模式,同时保持认知负荷低。

例如,如果我们想组合一个处理API调用的管道,我们将创建类似以下的内容

$processApiRequest = (new Pipeline)
    ->pipe(new ExecuteHttpRequest) // 2
    ->pipe(new ParseJsonResponse); // 3
    
$pipeline = (new Pipeline)
    ->pipe(new ConvertToPsr7Request) // 1
    ->pipe($processApiRequest) // (2,3)
    ->pipe(new ConvertToResponseDto); // 4 
    
(new Processor\FingersCrossed())->process($pipeline, new DeleteBlogPost($postId));

管道构建器

因为管道本身是不可变的,所以引入了管道构建器来促进管道的分布式组合。

管道构建器收集阶段,并允许您在任何给定时间创建管道。

use SyberIsle\Pipeline\Pipeline\SimpleBuilder;

// Prepare the builder
$pipelineBuilder = (new SimpleBuilder)
    ->add(new LogicalStage)
    ->add(new AnotherStage)
    ->add(new LastStage);

// Build the pipeline
$pipeline = $pipelineBuilder->build();

异常处理

在处理异常时,此包完全透明。在没有任何情况下,此包将捕获异常或静默错误。异常应根据具体情况处理。可以在阶段内部或在管道处理负载时处理。

$pipeline = (new Pipeline)->pipe(function () {
    throw new LogicException();
});
    
try {
    (new Processor\FingersCrossed())->process($pipeline, $payload);
} catch(LogicException $e) {
    // Handle the exception.
}

致谢

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件