bakame / spec
PHP 中的规范
Requires
- php: ^8.0
Requires (Dev)
- friends-of-phpspec/phpspec-code-coverage: ^v6.1.0
- friendsofphp/php-cs-fixer: ^v3.8.0
- phpspec/phpspec: ^7.2.0
- phpstan/phpstan: ^1.6.8
- phpstan/phpstan-strict-rules: ^1.2.3
- vimeo/psalm: ^4.23.0
This package is auto-updated.
Last update: 2024-08-23 10:28:15 UTC
README
此包为 PHP 提供了对规范模式的支持。它通过卸载所有繁琐的工作来帮助利用复杂的规范。实现规范模式变得简单,同时将所有逻辑连接留给了包。
虽然与框架无关,但您可以将此包轻松集成到任何 PHP 框架中。
系统需求
您需要
- PHP >= 8.0 但建议使用 PHP 的最新稳定版本
安装
使用 composer
composer require bakame/spec
或下载库并
- 使用任何其他 PSR-4 兼容的自动加载器。
- 使用如下所示的包自动加载脚本
require 'path/to/spec/repo/autoload.php'; use Bakame\Specification\Chain; $spec = Chain::one(new Rule1()) ->and(new Rule2(), new Rule3()) ->orNot(new Rule4()); $spec->isSatisfiedBy($subject);
这是什么?
"规范模式是一种特定的软件设计模式,通过使用布尔逻辑将业务规则链接在一起,可以重新组合业务规则。该模式通常用于领域驱动设计的上下文中。" -- 维基百科
用法
需要满足的每个规则都必须实现 Bakame\Specification\Specification
接口。
此接口仅包含一个方法 isSatisfiedBy(mixed $subject): bool
。该方法不应 抛出
异常,但如果它确实抛出异常,则没有机制 MUST 停止异常在方法外部传播。
以下是一个快速示例,说明如何使用此包。
首先,我们创建一个实现规范类。
<?php use Bakame\Specification\Specification; final class OverDueSpecification implements Specification { public function __construct( private DateTimeImmutable $date = new DateTimeImmutable('NOW', new DateTimeZone('UTC')) ) { } public function isSatisfiedBy(mixed $subject) : bool { return $subject instanceof Invoice && $subject->getDueDate() < $this->date; } }
然后使用 Bakame\Specification\Chain
类和创建的所有规范,我们根据业务规则应用所有规范。
以下是如何使用库对维基百科示例进行适配。
<?php use Bakame\Specification\Chain; $overDue = new OverDueSpecification(); $noticeSent = new NoticeSentSpecification(); $inCollection = new InCollectionSpecification(); $sendToCollection = Chain::one($overDue) ->and($noticeSent) ->andNot($inCollection); foreach ($service->getInvoices() as $invoice) { if ($sendToCollection->isSatisfiedBy($invoice)) { $invoice->sendToCollection(); } }
Bakame\Specification\Chain
类公开以下逻辑链接方法
为了启动一个新的规范逻辑链,类公开了 4 个命名构造函数
Bakame\Specification\Chain
的所有方法都接受可变数量的 Bakame\Specification\Specification
实现类,除了 Chain::not
方法,它不接受任何参数。
创建更复杂的规则变得非常简单,同样它们的维护也是如此。
有关如何验证主题列表的技巧。
数组
要过滤主题数组,可以使用 array_filter
函数
<?php $invoiceCollection = array_filter( fn (Invoice $invoice): bool => $sendToCollection->isSatisfiedBy($invoice), $respository->getInvoices() ); foreach ($invoiceCollection as $invoice) { $invoice->sendToCollection(); }
可遍历
要过滤可遍历结构或通用迭代器,可以使用 CallbackFilterIterator
类。
<?php $invoiceCollection = new CallbackFilterIterator( $respository->getInvoices(), fn (Invoice $invoice): bool => $sendToCollection->isSatisfiedBy($invoice), ); foreach ($invoiceCollection as $invoice) { $invoice->sendToCollection(); }
集合
该包可以直接用于支持 filter
方法的集合,如 Doctrine
集合类。
<?php $invoiceCollection = $respository->getInvoices()->filter( fn (Invoice $invoice): bool => $sendToCollection->isSatisfiedBy($invoice) ); foreach ($invoiceCollection as $invoice) { $invoice->sendToCollection(); }
集合宏
对于 Laravel 集合的替代方法是注册一个宏
<?php declare(strict_types=1); use Bakame\Specification\Specification; use Illuminate\Support\Collection; Collection::macro('satisfies', fn (Specification $specification): Collection => $this->filter( fn ($item): bool => $specification->isSatisfiedBy($item); ) );
然后按以下方式使用
$invoiceCollection = $invoices->all()->satifies($sendToCollection); foreach ($invoiceCollection as $invoice) { $invoice->sendToCollection(); }
贡献
欢迎贡献,并将得到充分认可。请参阅 CONTRIBUTING 和 CODE OF CONDUCT 了解详情。
测试
库
- 具有 PHPSpec 测试套件
- 具有使用 PHP CS Fixer 的编码风格合规性测试套件。
- 该文档使用了PHPStan和Psalm进行代码分析合规性测试套件。
要运行测试,请在项目文件夹中运行以下命令。
$ composer test
安全
如果您发现任何与安全相关的问题,请发送电子邮件至nyamsprod@gmail.com,而不是使用问题跟踪器。
致谢
署名
该包是greydnls在greydnls/spec上工作的分支。
许可证
MIT许可证(MIT)。有关更多信息,请参阅许可证文件。