chippyash/assembly-builder

轻量级函数式组装器模式,具有类似Scala的For Comprehension功能

3.0.0 2021-05-24 05:38 UTC

This package is auto-updated.

Last update: 2024-09-24 13:03:08 UTC


README

质量保证

PHP 5.6 PHP 7 Build Status Code Climate Test Coverage

上述徽章代表当前的开发分支。通常情况下,除非测试、覆盖率和使用性都符合要求,否则我不会向GitHub推送代码。在某些短时间内,这可能并不成立;比如放假期间,需要为其他下游项目编写代码等。如果您需要稳定版本的代码,请使用带有标签的版本。阅读“进一步文档”和“安装”。

此库的第2.0.0版本开始不再支持PHP5.4和5.5的开发者。如果您需要支持PHP 5.4或5.5,请使用版本>=1,<2

此库的第3.0.0版本开始不再支持PHP7.X的开发者。如果您需要支持PHP 7.X,请使用版本>=2,<3

是什么?

提供了一个组装器,Builder Pattern的轻量级变体。同时也提供了类似Scala的For Comprehension功能,(汇编器的简单衍生。)

为什么?

在我对Scala语言的研究中,我遇到了For Comprehension。事实证明,在本质上,它实际上是经典Builder Pattern的一个变体,但没有与Director相关的需求。

我进行了一些搜索,但找不到类似的东西,所以如果您知道任何东西,请告诉我。

那么它有什么用?

本质上,它提供了一个机制来收集“事物”,然后在稍后的某个时间点将它们组装在一起。在这个案例中,“事物”是函数。自从PHP中引入了Callable(或闭包)以来,PHP开发者的生活发生了一些变化。匿名函数以更简单的方式提供了一种做任何事情的自由(PHP始终有这样的能力)。

它真的很简单

  • 创建一个Assembler
  • 使用键(变量名)将一些函数附加到它上
    • 函数可以访问先前定义的函数(或存储的变量)
  • 组装一切(调用先前附加的函数)
  • 访问一个、一些或没有结果

examples/OneManCoffeeShop.php脚本能给出一个在相对简单场景中汇编器作用的风味示例。

examples/CarAssemblyLine.php要复杂一些,但展示了您如何将汇编器传递给各种过程,就像购物车一样,在未来某个时刻将其全部组装成最终产品。它还演示了汇编器的一个简单衍生,类似Scala的For Comprehension,因为PHP中For是一个保留字,所以被称为FFor

在大型系统中,您可能希望将汇编器用作应用程序中正在进行的“事物”的集合点。为此,您可以通过Assembler::get()获取单例实例。当然,您只能使用一次(因为后续对Assembler::get()的调用将返回相同的实例),所以请谨慎使用。

如何?

汇编器

创建一个汇编器

use Assembler\Assembler;

$myAssembler = Assembler::create();
//or to create the singleton instance
$myAssembler = Assembler::get();

向汇编器添加函数。这最初可能看起来有些奇怪。添加函数的模式是

Assembler->nameOfVar(function(){ return ...;});
//e.g.
$myAssembler->foo(function(){return 'foo';});

或者将多个组装项目串联起来

$myAssembler->foo(function(){return 'foo';})
    ->bar(function(){return 'bar';});

您可以通过传递名称作为参数到后续条目来引用预定义的条目。

$myAssembler->foo(function(){return 'foo';})
    ->bar(function($foo){return "$foo bar";});

在此阶段,汇编器尚未执行您的函数,因此您可以重新定义它们。

$myAssembler->foo(function(){return 'foo';})
    ->bar(function($foo){return "$foo bar";})
    ->foo(function(){return 'foo foo';});

要执行函数,请调用assemble()方法。

$myAssembler->foo(function(){return 'foo})
    ->bar(function($foo){return "$foo bar";})
    ->foo(function(){return 'foo foo';})
    ->assemble();

在此阶段,条目变为不可变,无法被覆盖。您可以继续添加更多条目,也许引用早期的条目,然后再次调用->assemble()来修复条目。

要从汇编器检索一个或多个值,请使用release()方法。release()接受一个或多个字符串,即您想要发布的项的名称。要发布单个项

$myFoo = Assembler::create()
    ->foo(function(){return 'foo})
    ->bar(function($foo){return "$foo bar";})
    ->foo(function(){return 'foo foo';})
    ->assemble()
    ->release('foo');

发布多个项将返回一个值数组,因此使用古老的PHP list()(或[])方法来访问它们可能是最简单的方法,例如。

list($myFoo, $myBar) = Assembler::create()
    ->foo(function(){return 'foo})
    ->bar(function($foo){return "$foo bar";})
    ->foo(function(){return 'foo foo';})
    ->assemble()
    ->release('foo', 'bar');

您可以使用merge()方法将一个汇编器合并到另一个汇编器中。

$worker1 = Assembler::create()
    ->foo(function(){return 'foo});
    
$worker2 = Assembler::create()
    ->bar(function($foo){return "$foo bar";})
    
$myFoo = $worker1->merge($worker2->assemble())
    ->assemble()
    ->release('foo');

您可以在创建(create()或get())汇编器时发送参数。这非常有用,可以防止您在函数定义期间使用use子句。在创建过程中发送的参数是不可变的,即您不能通过后来的声明来覆盖它们。

$a = 'foo';
$b = 'bar'

$value = Assembler::create(['a'=>$a, 'b'=>$b])
    ->foo(function($a, $b) { return "$a$b";})
    ->assemble()
    ->release('foo');
// $value == 'foobar'

//This will have no effect on 'a'
$value = Assembler::create(['a'=>$a, 'b'=>$b])
    ->a(function() {return 1;})
    ->foo(function($a, $b) { return "$a$b";})
    ->assemble()
    ->release('foo');

//without parameter injection
$value = Assembler::create()
    ->foo(function() use ($a, $b) { return "$a$b";})
    ->assemble()
    ->release('foo');

您可以使用ParameterGrabable特性来促进参数注入到create()构造函数中。

use Assembler\Traits\ParameterGrabable;
use Assembler\Assembler;

class myClass {
     use ParameterGrabable;

     static function foo($param1, $param2 = null) {
         $a = Assembler::create(self::grabFunctionParameters(__CLASS__, __FUNCTION__, func_get_args());
     }

     function bar($param1, $param2 = null) {
         $a = Assembler::create($this->grabMethodParameters(__CLASS__, __METHOD__, func_get_args());
     }
}

FFor

FFor类是汇编器的一个简单扩展,但有限制

  • 您不能通过get()创建单例FFor。请使用create()。FFor被视为语言结构
  • 您不能合并() FFor。
  • 还有一个额外的方法;fyield()。fyield()是->assemble()->release()的别名,并接受与release()相同的参数

请参阅examples/CarAssemblyLine.php脚本的用法示例。

更多文档

请注意,您在Github上看到的此文档的显示始终是最新dev-master。它描述的功能可能尚未发布。请查看您所编写的版本的文档或下载。

Uml diag

请参阅测试和测试合同以获取更多信息。

请查看ZF4 Packages以获取更多包

运行示例

虽然库本身除了PHP之外没有其他依赖项,但示例有。这些包含在composer requires-dev语句中,因此只要您已经包含了开发需求(Composer的默认设置),您就应该可以开始了。

更改库

  1. 将其分叉
  2. 编写测试
  3. 修改它
  4. 发起拉取请求

发现了一个您无法解决的bug吗?

  1. 将其分叉
  2. 编写测试
  3. 发起拉取请求

请注意。在您的拉取请求之前,请确保您已rebase到HEAD

或者 - 提出一个问题票。

在哪里?

该库托管在Github上。它可在Packagist.org上获取。

安装

安装Composer

对于生产

    "chippyash/assembly-builder": ">=3"

或者使用最新的,可能是不稳定的版本

    "chippyash/assembly-builder": "dev-master"

对于开发

克隆此存储库,然后在本地存储库根目录中运行Composer以拉入依赖项

    git clone git@github.com:chippyash/Assembly-Builder.git Assembler
    cd Assembler
    composer install

要运行测试

    cd Assembler
    vendor/bin/phpunit -c test/phpunit.xml test/

许可证

此软件库在BSD 3 Clause license下发布

此软件库的版权为(c) 2015,Ashley Kitson,英国

历史

V1.0.0 初始版本

V1.1.0 添加在汇编器和FFor创建中发送参数的能力

V1.1.1 修复参数顺序传递错误

V1.1.2 添加ParameterGrabable特性

V1.2.0 更新以使用Chippyash\Type V3

V1.2.1 添加到包的链接

V1.2.2 验证PHP 7兼容性

V1.2.3 更新对Monad的依赖

V1.2.4 更新构建脚本

版本1.2.5更新 composer - 由于packagist composer.json格式变更强制更新

版本2.0.0 兼容性中断。不支持旧版本PHP

版本2.1.0 许可证变更,从GPL V3更改为BSD 3条款

版本3.0.0 兼容性中断。不支持PHP <V8