8fold/php-foldable

此包已废弃,不再维护。未建议替代包。

开发流畅接口和管道模式的框架

1.3.1 2021-01-03 00:12 UTC

README

Foldable 是一个低级、轻量级的库,用于简化高级封装和流畅接口的创建。

安装

composer require 8fold/php-foldable

使用

可折叠对象 可以扩展 Fold 类,使用 FoldableImp 默认实现,或者实现 Foldable 接口。注意:Fold 类使用并实现了 Foldable 默认实现和接口。

class MyFoldable extends Fold
{
  public function append(string $string): MyFoldable
  {
    $this->main = $this->main . $string;

    return $this;

    // Note: If you prefer immutability, you can always create a new instance
    //       of the MyFoldable class:
    //
    //       return MyFoldable::fold(...$this->args(true));
  }
}

print MyFoldable::fold("Hello")->append(", World!")->unfold();
// output: Hello, World!

fold() 静态初始化器(或命名构造函数)可以接受无限数量的参数。对于默认实现,第一个参数存储为 main,其他参数存储为数组 args。为了帮助实现不可变性,你可以通过调用 args 方法来检索提供的参数;你也可以通过调用 args(true) 来指定你想要包括 main 在内的完整列表。

过滤器 是实现 __invoke 魔术方法的 PHP 类;因此它们在标准库中更像是一个命名空间的全局函数。

class Append extends Filter
{
  public function __invoke($using): string
  {
      if (is_a($using, Pipe::class)) {
          return $using->unfold() . $this->main;
      }
      return $using . $this->main;
  }
}

print Apply::append(", World!")->unfoldUsing("Hello");
// output: Hello, World!

class MyFoldable extends Fold
{
  public function append(string $string): MyFoldable
  {
    $this->main = Append::applyWith($string)->unfoldUsing($this->main);

    return $this;
  }
}

print MyFoldable::fold("Hello")->append(", World!")->unfold();
// output: Hello, World!

管道 可以用来从起点依次应用多个过滤器。

class Prepend extends Filter
{
  public function __invoke(string $using): string
  {
      return Append::applyWith($using)->unfoldUsing($this->main);
  }
}

$result = Pipe::fold("World",
  Apply::prepend("Hello, "),
  Apply::append("!")
)->unfold();
// output: Hello, World!

// you can allow filters to take pipes as well
$result = Pipe::fold("World",
  Apply::prepend(
    Pipe::fold("ello",
      Apply::prepend("H"),
      Apply::append(","),
      Apply::append(" ")
    )
  ),
  Apply::append("!")
)->unfold();

我们还在测试目录中提供了一个断言过滤器 PerformantEqualsTestFilter,可以用来测试 FoldablesFilters 的相等性和性能。

use PHPUnit\Framework\TestCase as PHPUnitTestCase;

use Eightfold\Foldable\Tests\PerformantEqualsTestFilter as AssertEquals;

class TestCase extends PHPUnitTestCase
{
  /**
  * @test
  */
  public function test_something()
  {
    AssertEquals::applyWith(
      "expected result",
      "expected type",
      0.4 // maximum milliseconds
    )->unfoldUsing(
      Pipe::fold("World",
        Apply::prepend(
          Pipe::fold("ello",
            Apply::prepend("H"),
            Apply::append(","),
            Apply::append(" ")
          )
        ),
        Apply::append("!")
      )
    );
  }
}

开始时间是初始化时开始,展开传递的 Foldable 或分配传递的值后停止。

详细信息

主要目标是

  1. 在提供灵活性的同时保证类型安全。
  2. 速度。这是一个面向高扩展性的低级库,旨在添加尽可能少的处理开销。我们的性能测试基准(大多数都是)是 0.3 毫秒。(如果你知道如何提高速度,请随时提交问题或 PR)。
  3. 反空值。尽可能不将 null 作为必需参数接受,并尽可能避免返回 null。我们不对它进行防御性处理;因此,大部分责任留给了用户。

其他