cptburke / application-primitives
有用的应用构建原语
0.1.1
2024-02-22 11:26 UTC
Requires
- php: >=8.0
Requires (Dev)
- phpspec/phpspec: ^7.1
Suggests
- cptburke/symfony-messenger-application: implementation of these primitives
- lambdish/phunctional: useful library for functional programming
This package is not auto-updated.
Last update: 2024-10-03 14:36:43 UTC
README
应用/服务(CQRS、DDD等)的有用构建块集合。
安装
composer require cptburke/application-primitives
使用
使用的一般想法,请参阅TODO以了解实现。
域
<?php use CptBurke\Application\Domain\EventAggregate; use CptBurke\Application\Domain\DomainEvent; use CptBurke\Application\Domain\DomainEventBus; use CptBurke\Application\Domain\DomainEventSubscriber; class DomainSpecificEvent implements DomainEvent {} class OtherDomainSpecificEvent implements DomainEvent {} class DomainObject { use EventAggregate; //... public function doSomething(): void { //... $this->raise(new DomainSpecificEvent()); } //... } class DomainService implements DomainEventSubscriber { private DomainEventBus $bus; //... public static function subscribedTo() : array { return [ OtherDomainSpecificEvent::class ]; } //... public function doSomethingInDomain(/* ... */): void { //... /** @var DomainObject $obj */ $obj->doSomething(); $this->bus->dispatch(...$obj->releaseEvents()); /* * [DomainSpecificEvent] */ } //... public function onOtherEvent(OtherDomainSpecificEvent $e): void { //... } }
应用
事件
<?php use CptBurke\Application\Event\ApplicationEvent; use CptBurke\Application\Event\ApplicationEventBus; use CptBurke\Application\Event\ApplicationEventSubscriber; class ApplicationSpecificEvent implements ApplicationEvent {} class OtherApplicationSpecificEvent implements ApplicationEvent {} class ApplicationAction implements ApplicationEventSubscriber { private ApplicationEventBus $bus; //... public static function subscribedTo() : array { return [ OtherApplicationSpecificEvent::class ]; } //... public function doAction(/* ... */): void { //... $this->bus->dispatch(new ApplicationSpecificEvent()); } //... public function onOtherEvent(OtherApplicationSpecificEvent $e): void { //... } }
命令
<?php use CptBurke\Application\Command\Command; use CptBurke\Application\Command\CommandBus; use CptBurke\Application\Command\CommandHandler; /** should be serializable pojo */ final class ToDo implements Command { /** * public string $foo; * public string $bar; */ } class DoSomething implements CommandHandler { //... public function __invoke(ToDo $command): void { //... } //... } class Controller { private CommandBus $bus; //... public function action(/* ... */): void { //... $this->bus->dispatch(new ToDo(), [/** extra context, e.g. execution time, ... */]); //... } //... }
查询
<?php use CptBurke\Application\Query\Query; use CptBurke\Application\Query\QueryBus; use CptBurke\Application\Query\QueryHandler; /** should be serializable pojo */ final class Question implements Query { /** * public int $page; */ } /** e.g. database query result as pojo */ final class Answer { /** * public int $page; * public array $data; */ } /** should be handled synchronous */ class AnswerSomething implements QueryHandler { //... public function __invoke(Question $command): Answer { //... } //... } class Controller { private QueryBus $bus; //... public function action(/* ... */): void { //... $answer = $this->bus->ask(new Question()); //... } //... }
反射/框架工具
<?php use CptBurke\Application\Reflection\CallableExtractor; use CptBurke\Application\Command\Command; use CptBurke\Application\Domain\DomainEvent; $extractor = new CallableExtractor(); $commandMapping = $extractor->fromCallables( [Command::class, new CommandHandler()], ); $eventMapping = $extractor->fromSubscribers( [DomainEvent::class, new DomainEventHandler()], [DomainEvent::class, new OtherDomainEventHandler()] )