Skip to content

Commit

Permalink
Merge 29df5f8 into ddb3738
Browse files Browse the repository at this point in the history
  • Loading branch information
ericksonreyes committed May 14, 2019
2 parents ddb3738 + 29df5f8 commit ac17bd3
Show file tree
Hide file tree
Showing 12 changed files with 350 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use EricksonReyes\DomainDrivenDesign\Application\Exception\DuplicateCommandHandlerException;
use EricksonReyes\DomainDrivenDesign\Application\Exception\MissingHandlerMethodException;
use EricksonReyes\DomainDrivenDesign\Application\Exception\UnhandledCommandException;
use EricksonReyes\DomainDrivenDesign\Infrastructure\CommandBus as CommandBusInterface;
use PhpSpec\ObjectBehavior;

class CommandBusSpec extends ObjectBehavior
Expand All @@ -26,9 +27,13 @@ public function let()
$this->handler = new MockHandler();
}

/**
*
*/
public function it_is_initializable()
{
$this->shouldHaveType(CommandBus::class);
$this->shouldHaveType(CommandBusInterface::class);
}

public function it_accepts_handlers()
Expand Down
90 changes: 90 additions & 0 deletions spec/EricksonReyes/DomainDrivenDesign/Application/EventBusSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php

namespace spec\EricksonReyes\DomainDrivenDesign\Application;

use EricksonReyes\DomainDrivenDesign\Application\EventBus;
use EricksonReyes\DomainDrivenDesign\Application\Exception\DuplicateEventHandlerException;
use EricksonReyes\DomainDrivenDesign\Domain\Event;
use EricksonReyes\DomainDrivenDesign\Infrastructure\EventBus as EventBusInterface;
use EricksonReyes\DomainDrivenDesign\Infrastructure\EventHandler;
use EricksonReyes\DomainDrivenDesign\Infrastructure\ExceptionHandler;
use Faker\Factory;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use RuntimeException;

class EventBusSpec extends ObjectBehavior
{
/**
* @var EventHandler[]
*/
private $handlers;

public function it_is_initializable()
{
$this->shouldHaveType(EventBus::class);
$this->shouldHaveType(EventBusInterface::class);
}

public function it_registers_handlers(EventHandler $eventHandler)
{
$this->register($eventHandler)->shouldBeNull();
}

public function it_stores_handlers(EventHandler $eventHandler)
{
$this->register($eventHandler);
$this->handlers()->shouldHaveCount(1);
}

public function it_prevents_duplicate_event_handlers(EventHandler $eventHandler)
{
$eventHandler->name()->shouldBeCalled()->willReturn(Factory::create()->word);
$this->register($eventHandler);
$this->shouldThrow(DuplicateEventHandlerException::class)->during('register', [
$eventHandler
]);
}

public function it_dispatches_events(
EventHandler $interestedEventHandler,
EventHandler $eventHandler,
Event $event
)
{
$interestedEventHandler->isInterestedInThis($event)->shouldBeCalled()->willReturn(true);
$eventHandler->isInterestedInThis($event)->shouldBeCalled()->willReturn(false);
$interestedEventHandler->beNotifiedAbout($event)->shouldBeCalled();

$this->register($interestedEventHandler);
$this->register($eventHandler);
$this->dispatch($event)->shouldBeNull();
}

public function it_can_have_exception_handlers(
ExceptionHandler $exceptionHandler,
EventHandler $eventHandler,
MockBuggedEventHandler $buggedEventHandler,
EventHandler $anotherEventHandler,
Event $event
)
{
$this->registerExceptionHandler($exceptionHandler)->shouldBeNull();

$this->register($eventHandler);
$this->register($buggedEventHandler);
$this->register($anotherEventHandler);

$eventHandler->beNotifiedAbout($event)->shouldBeCalled();
$buggedEventHandler->beNotifiedAbout($event)->shouldBeCalled()->willThrow(RuntimeException::class);
$anotherEventHandler->beNotifiedAbout($event)->shouldBeCalled();

$eventHandler->isInterestedInThis($event)->shouldBeCalled()->willReturn(true);
$buggedEventHandler->isInterestedInThis($event)->shouldBeCalled()->willReturn(true);
$anotherEventHandler->isInterestedInThis($event)->shouldBeCalled()->willReturn(true);

$exceptionHandler->handleThis(Argument::type(RuntimeException::class))->shouldBeCalled();

$this->dispatch($event);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
/**
* Created by PhpStorm.
* User: ericksonreyes
* Date: 2019-05-14
* Time: 17:35
*/

namespace spec\EricksonReyes\DomainDrivenDesign\Application;


use EricksonReyes\DomainDrivenDesign\Domain\Event;
use EricksonReyes\DomainDrivenDesign\Infrastructure\EventHandler;
use RuntimeException;

class MockBuggedEventHandler implements EventHandler
{
/**
* @return string
*/
public function name(): string
{
return '';
}

/**
* @param Event $event
* @return bool
*/
public function isInterestedInThis(Event $event): bool
{
return true;
}

/**
* @param Event $event
*/
public function beNotifiedAbout(Event $event): void
{
throw new RuntimeException('Just a mock runtime exception.');
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
use EricksonReyes\DomainDrivenDesign\Application\Exception\DuplicateCommandHandlerException;
use EricksonReyes\DomainDrivenDesign\Application\Exception\MissingHandlerMethodException;
use EricksonReyes\DomainDrivenDesign\Application\Exception\UnhandledCommandException;
use EricksonReyes\DomainDrivenDesign\Infrastructure\CommandBus as CommandBusInterface;

/**
* Class CommandHandler
* @package EricksonReyes\DomainDrivenDesign\Application
*/
class CommandBus
class CommandBus implements CommandBusInterface
{

/**
Expand All @@ -33,7 +34,7 @@ public function addHandler($commandHandlerInstance, string $commandClassName): v
);
}

if ($this->alreadyHandlesThisCommand($commandHandlerInstance, $commandClassName)) {
if ($this->commandIsBeingHandledAlready($commandHandlerInstance, $commandClassName)) {
throw new DuplicateCommandHandlerException(
"{$handlerInstanceClassName} is already handling {$commandClassName}."
);
Expand Down Expand Up @@ -81,7 +82,7 @@ private function commands(): array
* @param string $commandClassName
* @return bool
*/
private function alreadyHandlesThisCommand($commandHandlerInstance, string $commandClassName): bool
private function commandIsBeingHandledAlready($commandHandlerInstance, string $commandClassName): bool
{
return in_array($commandHandlerInstance, $this->commands[$commandClassName], true);
}
Expand Down
81 changes: 81 additions & 0 deletions src/EricksonReyes/DomainDrivenDesign/Application/EventBus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

namespace EricksonReyes\DomainDrivenDesign\Application;

use EricksonReyes\DomainDrivenDesign\Application\Exception\DuplicateEventHandlerException;
use EricksonReyes\DomainDrivenDesign\Domain\Event;
use EricksonReyes\DomainDrivenDesign\Infrastructure\EventBus as EventBusInterface;
use EricksonReyes\DomainDrivenDesign\Infrastructure\EventHandler;
use EricksonReyes\DomainDrivenDesign\Infrastructure\ExceptionHandler;
use Exception;

class EventBus implements EventBusInterface
{
/**
* @var EventHandler[]
*/
private $handlers = [];

/**
* @var ExceptionHandler[]
*/
private $exceptionHandlers = [];

/**
* @param EventHandler $handler
*/
public function register(EventHandler $handler): void
{
foreach ($this->handlers() as $registeredHandler) {
$registeredHandlerClassName = get_class($registeredHandler);
if ($handler instanceof $registeredHandlerClassName) {
throw new DuplicateEventHandlerException(
$handler->name() . ' is already registered in the event bus.'
);
}
}
$this->handlers[] = $handler;
}

/**
* @param ExceptionHandler $exceptionHandler
*/
public function registerExceptionHandler(ExceptionHandler $exceptionHandler): void
{
$this->exceptionHandlers[] = $exceptionHandler;
}

/**
* @param Event $event
*/
public function dispatch(Event $event): void
{
foreach ($this->handlers() as $handler) {
try {
if ($handler->isInterestedInThis($event)) {
$handler->beNotifiedAbout($event);
}
} catch (Exception $exception) {
foreach ($this->exceptionHandlers() as $exceptionHandler) {
$exceptionHandler->handleThis($exception);
}
}
}
}

/**
* @return EventHandler[]
*/
public function handlers(): array
{
return $this->handlers;
}

/**
* @return ExceptionHandler[]
*/
public function exceptionHandlers(): array
{
return $this->exceptionHandlers;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

namespace EricksonReyes\DomainDrivenDesign\Application\Exception;

use InvalidArgumentException;
use RuntimeException;

/**
* Class DuplicateCommandHandlerException
* @package EricksonReyes\DomainDrivenDesign\Application\Exception
*/
final class DuplicateCommandHandlerException extends InvalidArgumentException
final class DuplicateCommandHandlerException extends RuntimeException
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace EricksonReyes\DomainDrivenDesign\Application\Exception;

use RuntimeException;

/**
* Class DuplicateEventHandlerException
* @package EricksonReyes\DomainDrivenDesign\Application\Exception
*/
final class DuplicateEventHandlerException extends RuntimeException
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

namespace EricksonReyes\DomainDrivenDesign\Common\Exception;


use BadMethodCallException;

final class DomainEventOwnershipException extends BadMethodCallException
{

}
}
31 changes: 31 additions & 0 deletions src/EricksonReyes/DomainDrivenDesign/Infrastructure/CommandBus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php
/**
* Created by PhpStorm.
* User: ericksonreyes
* Date: 2019-05-14
* Time: 16:56
*/

namespace EricksonReyes\DomainDrivenDesign\Infrastructure;

use EricksonReyes\DomainDrivenDesign\Application\Exception\UnhandledCommandException;

/**
* Class CommandHandler
* @package EricksonReyes\DomainDrivenDesign\Application
*/
interface CommandBus
{
/**
* @param $commandHandlerInstance
* @param string $commandClassName
*/
public function addHandler($commandHandlerInstance, string $commandClassName): void;

/**
* @param $commandClassInstance
* @return array
* @throws UnhandledCommandException
*/
public function execute($commandClassInstance): array;
}
34 changes: 34 additions & 0 deletions src/EricksonReyes/DomainDrivenDesign/Infrastructure/EventBus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php
/**
* Created by PhpStorm.
* User: ericksonreyes
* Date: 2019-05-14
* Time: 17:11
*/

namespace EricksonReyes\DomainDrivenDesign\Infrastructure;

use EricksonReyes\DomainDrivenDesign\Domain\Event;

interface EventBus
{
/**
* @param EventHandler $handler
*/
public function register(EventHandler $handler): void;

/**
* @param Event $event
*/
public function dispatch(Event $event): void;

/**
* @return EventHandler[]
*/
public function handlers(): array;

/**
* @param ExceptionHandler $exceptionHandler
*/
public function registerExceptionHandler(ExceptionHandler $exceptionHandler): void;
}

0 comments on commit ac17bd3

Please sign in to comment.