phpgears / cqrs
CQRS 基础
Requires
- php: ^7.1
- phpgears/dto: ~0.3.1
Requires (Dev)
- brainmaestro/composer-git-hooks: ^2.8
- friendsofphp/php-cs-fixer: ^2.16
- infection/infection: ^0.13|^0.15
- overtrue/phplint: ^1.2
- phpmd/phpmd: ^2.8
- phpstan/extension-installer: ^1.0.3
- phpstan/phpstan: ^0.12
- phpstan/phpstan-deprecation-rules: ^0.12
- phpstan/phpstan-strict-rules: ^0.12
- phpunit/phpunit: ^7.5|^8.0
- povils/phpmnd: ^2.1
- roave/security-advisories: dev-master
- sebastian/phpcpd: ^4.0
- squizlabs/php_codesniffer: ^3.5
- thecodingmachine/phpstan-strict-rules: ^0.12
This package is auto-updated.
Last update: 2024-08-25 07:23:49 UTC
README
CQRS
CQRS 基类和处理接口
此包仅提供 CQRS 的构建块
安装
Composer
composer require phpgears/cqrs
用法
要求 composer 自动加载文件
require './vendor/autoload.php';
命令
命令是 DTO,携带执行动作所需的所有信息
您可以通过实现 Gears\CQRS\Command
或扩展 Gears\CQRS\AbstractCommand
(确保命令不可变,且负载仅由 标量值 组成,这是一个非常有趣的特性)来创建自己的命令。AbstractCommand 有一个受保护的构造函数,强制您创建自定义的静态命名构造函数
use Gears\CQRS\AbstractCommand; class CreateUserCommand extends AbstractCommand { public static function fromPersonalData( string $name, string lastname, \DateTimeImmutable $birthDate ): self { return new self([ 'name' => $name, 'lastname' => $lastname, 'birthDate' => $birthDate->format('U'), ]); } }
如果没有负载的命令,您可以扩展 Gears\CQRS\AbstractEmptyCommand
use Gears\CQRS\AbstractEmptyCommand; class CreateUserCommand extends AbstractEmptyCommand { public static function instance(): self { return new self(); } }
异步命令
如果命令的所有负载都由标量值组成,则将命令处理委托给消息队列系统(如 RabbitMQ、Gearman 或 Apache Kafka)时很有用,因为任何格式和语言中序列化/反序列化标量值都很简单
异步行为必须在 CommandBus 级别实现,命令总线必须能够识别异步命令(通过负载参数识别实现接口的命令映射等)并将它们排队
如果您想在 CommandBus 上实现异步行为,请查看 phpgears/cqrs-async,在那里您将找到启动异步命令总线所需的所有必要组件,例如使用 queue-interop 与 phpgears/cqrs-async-queue-interop
查询
查询是 DTO,携带发起数据源请求所需的所有信息
您可以通过实现 Gears\CQRS\Query
或扩展 Gears\CQRS\AbstractQuery
(确保查询不可变,且负载仅由标量值组成)来创建自己的查询。AbstractQuery 有一个受保护的构造函数,强制您创建自定义的静态命名构造函数
use Gears\CQRS\AbstractQuery; class FindUserQuery extends AbstractQuery { public static function fromName(string $name): self { return new self(['name' => $name]); } }
如果没有负载的查询,您可以扩展 Gears\CQRS\AbstractEmptyQuery
use Gears\CQRS\AbstractEmptyQuery; class FindAllUsersQuery extends AbstractEmptyQuery { public static function instance(): self { return new self(); } }
处理器
将命令和查询交给相应的总线上的 Gears\CQRS\CommandHandler
和 Gears\CQRS\QueryHandler
AbstractCommandHandler
和 AbstractQueryHandler
包含在此包中,这些抽象类验证命令/查询的类型,这样您就可以专注于实现处理逻辑
class CreateUserCommandHandler extends AbstractCommandHandler { protected function getSupportedCommandType(): string { return CreateUserCommand::class; } protected function handleCommand(Command $command): void { /* @var CreateUserCommand $command */ $user = new User( $command->getName(), $command->getLastname(), $command->getBirthDate() ); // ... } } class FindUserQueryHandler extends AbstractQueryHandler { protected function getSupportedQueryType(): string { return FindUserQuery::class; } protected function handleCommand(Query $query): DTO { /* @var FindUserQuery $query */ // Retrieve user from persistence by it's name $query->getName() return new UserDTO(/* parameters */); } }
请查看 phpgears/dto 以更好地了解命令和查询是如何从 DTO 中构建的以及它们如何保存其负载
总线
仅提供 Gears\CQRS\CommandBus
和 Gears\CQRS\QueryBus
接口,您可以通过添加适配器层轻松使用任何可用的优秀总线库
实现
目前可用的 CQRS 总线实现
- phpgears/cqrs-symfony-messenger 使用 Symfony 的 Messenger
- phpgears/cqrs-tactician 使用 League 的 Tactician
贡献
发现了一个错误或有一个功能请求? 请创建一个新问题。在创建之前,请查看现有的问题。
请参阅 CONTRIBUTING.md 文件
许可证
请参阅源代码中包含的LICENSE文件,以获取许可证条款的副本。