command bus !== ООП?
Re: command bus !== ООП?
Может глупый вопрос задам, но все-же.
К какому слою относится шина (интерфейс)? К прикладному?
К какому слою относится шина (интерфейс)? К прикладному?
Re: command bus !== ООП?
Но реализация шины может быть в инфраструктуре или презентационном (если в шине используем \Yii)?
Re: command bus !== ООП?
А как поступить, если в хендлере мне нужен логгер?
1. Делать свой адаптер и прокидывать в хендлер или
2. реализовать хендлер в инфраструктуре и прокинуть йиишный логгер?
1. Делать свой адаптер и прокидывать в хендлер или
2. реализовать хендлер в инфраструктуре и прокинуть йиишный логгер?
Re: command bus !== ООП?
презентационный - это адаптер приложения во внешний мир, принимает реквесты, отдает респонсы.
Реализация шины может быть в приложении или в инфраструктуре. Я предпочитаю такие вещи выносить в отдельные модули, а непосредственно в слое оставлять только фабрику.
Re: command bus !== ООП?
Не хочу создавать новую тему, спрошу тут.
App слой может знать об инфраструктуре?
Мои команды лежат в app слое, но шина валидации лежит в инфраструктуре (и все интерфейсы относящиеся конкретно к этой шине).
Так вот, команды и валидаторы знают, что в инфраструктуре есть некие интерфейсы для шины валидации (CommandValidatorAwareInterface, CommandValidatorInterface).
Нужно ли перенести эти интерфейсы в app слой? Или как-то по другому их распределить? Или все в порядке?
App слой может знать об инфраструктуре?
Мои команды лежат в app слое, но шина валидации лежит в инфраструктуре (и все интерфейсы относящиеся конкретно к этой шине).
Так вот, команды и валидаторы знают, что в инфраструктуре есть некие интерфейсы для шины валидации (CommandValidatorAwareInterface, CommandValidatorInterface).
Нужно ли перенести эти интерфейсы в app слой? Или как-то по другому их распределить? Или все в порядке?
Re: command bus !== ООП?
Код: Выделить всё
// infrastructure
abstract class BaseCommandValidator implements CommandValidatorInterface
{
protected $errors = [];
public function getErrors(): array
{
return $this->errors;
}
}
Код: Выделить всё
// application
class LoginValidator extends BaseCommandValidator
{
/**
* @var LoginCommand
*/
private $command;
public function __construct(LoginCommand $command)
{
$this->command = $command;
}
public function validate(): bool
{
return true;
}
}
Код: Выделить всё
// application
class LoginCommand implements CommandHandlerAwareInterface, CommandValidatorAwareInterface
{
/**
* @var string
*/
public $email;
/**
* @var string
*/
public $password;
/**
* @var int
*/
public $expirationTime;
public function __construct(string $email, string $password, int $expirationTime)
{
$this->email = $email;
$this->password = $password;
$this->expirationTime = $expirationTime;
}
public function getHandlerClass(): string
{
return LoginHandler::class;
}
public function getValidatorClass(): string
{
return LoginValidator::class;
}
}
Код: Выделить всё
// infrastructure
class ValidationCommandBus implements CommandBusInterface
{
/**
* @var CommandBusInterface
*/
private $next;
/**
* @var Container
*/
private $container;
public function __construct(CommandBusInterface $next, Container $container)
{
$this->next = $next;
$this->container = $container;
}
public function execute($command): CommandResult
{
if ($command instanceof CommandValidatorAwareInterface) {
$validator = $this->container->get($command->getValidatorClass(), [$command]);
if (!$validator instanceof CommandValidatorInterface) {
throw new \UnexpectedValueException('Validator must implement CommandValidatorInterface.');
}
if (!$validator->validate()) {
return CommandResult::failed($validator->getErrors())->withScope('validation');
}
}
return $this->next->execute($command);
}
}
Re: command bus !== ООП?
Это нормально, когда app слой использует интерфейсы из инфраструктурного слоя?
О каких интерфейсах речь спросите вы?
В инфраструктуре лежат фабрики хендлеров и валидаторов, которые используются шиной, и, эти реализации фабрик из инфраструктуры используют интерфейсы (CommandHandlerAwareInterface, CommandValidatorAwareInterface), что бы определить класс хендлера и валидотора. Соответственно, комманды должны эти интерфейсы заимплементить. Получается, что app слой зависит от инфраструктуры напрямую.
Норм это или проблема?
P.S. CommandHandlerAwareInterface, CommandValidatorAwareInterface тоже инфраструктурные, лежат рядом с фабриками.
О каких интерфейсах речь спросите вы?
В инфраструктуре лежат фабрики хендлеров и валидаторов, которые используются шиной, и, эти реализации фабрик из инфраструктуры используют интерфейсы (CommandHandlerAwareInterface, CommandValidatorAwareInterface), что бы определить класс хендлера и валидотора. Соответственно, комманды должны эти интерфейсы заимплементить. Получается, что app слой зависит от инфраструктуры напрямую.
Норм это или проблема?
P.S. CommandHandlerAwareInterface, CommandValidatorAwareInterface тоже инфраструктурные, лежат рядом с фабриками.
-
- Сообщения: 83
- Зарегистрирован: 2017.07.04, 20:53
Re: command bus !== ООП?
Не норм. App layer об инфраструктуре ничего знать не должен.
Re: command bus !== ООП?
вики: инфраструктура - комплекс взаимосвязанных обслуживающих структур или объектов, составляющих и обеспечивающих основу функционирования системы
ComamndHandler - это сущность слоя Application. Почему она в инфре?
В инфре только реализации, и то не все. Часть функционала надо выносить в модули.
Вот у тебя есть в приложении модули Blog, Shop, Api. Все три модуля используют шину, шина - сущность уровня приложения, ее надо вынести в модуль MessageBus и создавать в модуле Application, который будет ядром приложения, объединяющим модули. В разных модулях понадобится HttpClient. Надо вынести в модуль HttpClient. Причем модуль может состоять только из одной фабрики, создающей например инстанс GuzzleClient. Можно написать свой интерфейс для клиента, адаптер клиента над газзлом и фабрику. Можно свой клиент написать на чем угодно.
ComamndHandler - это сущность слоя Application. Почему она в инфре?
В инфре только реализации, и то не все. Часть функционала надо выносить в модули.
Вот у тебя есть в приложении модули Blog, Shop, Api. Все три модуля используют шину, шина - сущность уровня приложения, ее надо вынести в модуль MessageBus и создавать в модуле Application, который будет ядром приложения, объединяющим модули. В разных модулях понадобится HttpClient. Надо вынести в модуль HttpClient. Причем модуль может состоять только из одной фабрики, создающей например инстанс GuzzleClient. Можно написать свой интерфейс для клиента, адаптер клиента над газзлом и фабрику. Можно свой клиент написать на чем угодно.
Re: command bus !== ООП?
Что бы было наглядно, структура всего на данный момент