waterloomatt/pipeline

一个简单的逐步处理工具。

v0.0.1-alpha 2021-11-12 01:45 UTC

This package is auto-updated.

Last update: 2024-09-17 00:00:13 UTC


README

waterloomatt / pipeline

基于 Laravel的管道,这个小巨人可以对任何对象进行逐步处理。

安装

此包目前处于alpha阶段,您应小心在玩具应用之外的环境中运行它。话虽如此,我已经在生产环境中使用这个管道类超过一年,没有遇到任何问题。

composer require waterloomatt/pipeline:v0.0.1-alpha

概述

想象一下,在您的系统中发生了一个事件,比如上传了CSV文件,并触发了一些动作,

  1. 文件被验证(例如,大小、扩展名、MIME类型等)
  2. 文件被处理(例如,解析并提取到关系型数据库中)
  3. 文件被存档(例如,移动到远程共享中)
  4. 需要发送通知(例如,向商业用户和最终用户发送电子邮件)

您可能有一些对象负责这些步骤中的每一个,

  1. 一个 $validator
  2. 一个 $processor
  3. 一个 $archiver
  4. 一个 $notifier

好的。在一个传统的OOP应用程序中,调用代码可能看起来像这样,

$validator->validate($file);
$processor->process($file);
$mover->move($file);
$notifier->notify($file);

好的。没有什么问题。这个逻辑可以存在于任何地方,但在传统的MVC应用程序中,它可能存在于控制器、模型或这些辅助组件中。

那么,管道是如何做到的呢?

$pipes = [
    $validator,
    $processor,
    $archiver,
    $notifier
];

(new Pipeline())
    ->send($file)
    ->through($pipes)
    ->thenReturn();

是的。就这么简单。让我们看看一些示例。我们会从简单开始,逐步深入。

管道可以是闭包

$pipes = [
    // Multiply by 10
    function ($input, $next) {
        $input = $input * 10;
        return $next($input);
    },

    // Divide by 5
    function ($input, $next) {
        $input = $input / 5;
        return $next($input);
    },

    // Add 1
    function ($input, $next) {
        $input = $input + 1;
        return $next($input);
    },
];


$output = (new Pipeline())
    ->send(10)           // Start with 10
    ->through($pipes)    // Multiply by 10, divide by 5, add 1
    ->thenReturn();
    
// Output: 21

管道可以是类

class Validate
{
    public function handle(File $file, Closure $next)
    {        
        // ... business logic ...
    
        return $next($file);
    }
}

class Process
{
    public function handle(File $file, Closure $next)
    {        
        // ... business logic ...
    
        return $next($file);
    }
}

class Archive
{
    public function handle(File $file, Closure $next)
    {        
        // ... business logic ...
    
        return $next($file);
    }
}

class Notify
{
    public function handle(File $file, Closure $next)
    {        
        // ... business logic ...
    
        return $next($file);
    }
}

$pipes = [
    new Validate(),
    new Process(),
    new Archive(),
    new Notify()
];

(new Pipeline())
    ->send(new File())   // Start with a file
    ->through($pipes)    // validate, process, archive, notify
    ->thenReturn();