php-ddd / domain-event
用于管理领域和事件的库
v1.0.1
2015-08-08 08:49 UTC
Requires
- php: >=5.3.3
Requires (Dev)
- fabpot/php-cs-fixer: ^1.8.1
- phploc/phploc: ^2.1.3
- phpmd/phpmd: ^2.2.3
- phpunit/phpunit: ^4.7.0
This package is not auto-updated.
Last update: 2024-09-14 17:03:57 UTC
README
此库允许您集中精力在应用程序最重要的部分:领域。
根据Eric Evans的《领域驱动设计》一书,您的领域应由聚合组成。
每个聚合由一个AggregateRoot和一些ObjectValue组成。
此库专注于AggregateRoot,并提供管理聚合发生事件的帮助程序。
用法
以下示例将更好地解释此库的目的
use PhpDDD\Domain\AbstractAggregateRoot; class PurchaseOrder extends AbstractAggregateRoot { /** * @var mixed */ private $customerId; /** * Try to create a new PurchaseOrder for a client. */ public function __construct(Customer $customer) { // Tests that some business rules are followed. if (false === $customer->isActive()) { throw new MyDomainException('The customer need to be active.'); } // ... // Since every rules are validated, we can simulate the creation of the Event associated // This allows us to have less redundant code $this->apply(new PurchaseOrderCreated($customer, new DateTime())); // This is equivalent as // $this->customerId = $customer->getId(); // $this->events[] = new PurchaseOrderCreated($customer, new DateTime()); // but we are not allowing to add event directly. } /** * The apply() method will automatically call this method. * Since it's an event you should never do some tests in this method. * Try to think that an Event is something that happened in the past. * You can not modify what happened. The only thing that you can do is create another event to compensate. */ protected function applyPurchaseOrderCreated(PurchaseOrderCreated $event) { $this->customerId = $event->getCustomer()->getId(); } }
这种方法的优点是,您然后可以监听AggregateRoot产生的每个事件,并进行一些与业务领域不直接相关的工作,如发送电子邮件。
use PhpDDD\Domain\Event\Listener\AbstractEventListener; class SendEmailOnPurchaseOrderCreated extends AbstractEventListener { private $mailer; public function __construct($mailer) { $this->mailer = $mailer; } /** * {@inheritDoc} */ public function getSupportedEventClassName() { return 'PurchaseOrderCreated'; // Should be the fully qualified class name of the event } /** * {@inheritDoc} */ public function handle(EventInterface $event) { $this->mailer->send('to@you.com', 'Purchase order created for customer #' . $event->getCustomer()->getId()); } }
为了使项目知道有一个EventListener绑定到事件,您应该使用EventBus
// first the locator $locator = new \PhpDDD\Domain\Event\Listener\Locator\EventListenerLocator(); $locator->register('PurchaseOrderCreated', new SendEmailOnPurchaseOrderCreated(/* $mailer */)); // then the EventBus $bus = new \PhpDDD\Domain\Event\Bus\EventBus($locator); // do what you need to do on your Domain $aggregateRoot = new PurchaseOrder(new Customer(1)); // Then apply EventListeners $events = $aggregateRoot->pullEvents(); // this will clear the list of event in your AggregateRoot so an Event is trigger only once // You can have more than one event at a time. foreach($events as $event) { $bus->publish($event); }