command bus !== ООП?

Обсуждаем, как правильно строить приложения
Bio man
Сообщения: 609
Зарегистрирован: 2013.07.22, 10:40

Re: command bus !== ООП?

Сообщение Bio man »

Может глупый вопрос задам, но все-же.
К какому слою относится шина (интерфейс)? К прикладному?
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: command bus !== ООП?

Сообщение zelenin »

Bio man писал(а): 2018.01.16, 14:28 Может глупый вопрос задам, но все-же.
К какому слою относится шина (интерфейс)? К прикладному?
к слою приложения/сервисному слою. оркестратор всего что происходит в приложении.
Bio man
Сообщения: 609
Зарегистрирован: 2013.07.22, 10:40

Re: command bus !== ООП?

Сообщение Bio man »

Но реализация шины может быть в инфраструктуре или презентационном (если в шине используем \Yii)?
Bio man
Сообщения: 609
Зарегистрирован: 2013.07.22, 10:40

Re: command bus !== ООП?

Сообщение Bio man »

А как поступить, если в хендлере мне нужен логгер?
1. Делать свой адаптер и прокидывать в хендлер или
2. реализовать хендлер в инфраструктуре и прокинуть йиишный логгер?
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: command bus !== ООП?

Сообщение zelenin »

Bio man писал(а): 2018.01.16, 14:34 Но реализация шины может быть в инфраструктуре или презентационном (если в шине используем \Yii)?
презентационный - это адаптер приложения во внешний мир, принимает реквесты, отдает респонсы.
Реализация шины может быть в приложении или в инфраструктуре. Я предпочитаю такие вещи выносить в отдельные модули, а непосредственно в слое оставлять только фабрику.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: command bus !== ООП?

Сообщение zelenin »

Bio man писал(а): 2018.01.16, 14:37 А как поступить, если в хендлере мне нужен логгер?
1. Делать свой адаптер и прокидывать в хендлер или
2. реализовать хендлер в инфраструктуре и прокинуть йиишный логгер?
хэндлер же ваш? отредактируйте его.
Аватара пользователя
ElisDN
Сообщения: 5841
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: command bus !== ООП?

Сообщение ElisDN »

Bio man писал(а): 2018.01.16, 14:37 А как поступить, если в хендлере мне нужен логгер?
Принять Psr\ Log\LoggerInterface и в инфраструктуре сочинить адаптер для Yii-шного.
Bio man
Сообщения: 609
Зарегистрирован: 2013.07.22, 10:40

Re: command bus !== ООП?

Сообщение Bio man »

Не хочу создавать новую тему, спрошу тут.
App слой может знать об инфраструктуре?

Мои команды лежат в app слое, но шина валидации лежит в инфраструктуре (и все интерфейсы относящиеся конкретно к этой шине).
Так вот, команды и валидаторы знают, что в инфраструктуре есть некие интерфейсы для шины валидации (CommandValidatorAwareInterface, CommandValidatorInterface).
Нужно ли перенести эти интерфейсы в app слой? Или как-то по другому их распределить? Или все в порядке?
Bio man
Сообщения: 609
Зарегистрирован: 2013.07.22, 10:40

Re: command bus !== ООП?

Сообщение Bio man »

Код: Выделить всё

// 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);
    }
}
sda
Сообщения: 334
Зарегистрирован: 2013.12.19, 09:29

Re: command bus !== ООП?

Сообщение sda »

Bio man писал(а): 2018.01.16, 23:36 Нужно ли перенести эти интерфейсы в app слой?
нужно
Bio man
Сообщения: 609
Зарегистрирован: 2013.07.22, 10:40

Re: command bus !== ООП?

Сообщение Bio man »

Это нормально, когда app слой использует интерфейсы из инфраструктурного слоя?
О каких интерфейсах речь спросите вы?
В инфраструктуре лежат фабрики хендлеров и валидаторов, которые используются шиной, и, эти реализации фабрик из инфраструктуры используют интерфейсы (CommandHandlerAwareInterface, CommandValidatorAwareInterface), что бы определить класс хендлера и валидотора. Соответственно, комманды должны эти интерфейсы заимплементить. Получается, что app слой зависит от инфраструктуры напрямую.
Норм это или проблема?
P.S. CommandHandlerAwareInterface, CommandValidatorAwareInterface тоже инфраструктурные, лежат рядом с фабриками.
noLogicOnlyWar
Сообщения: 83
Зарегистрирован: 2017.07.04, 20:53

Re: command bus !== ООП?

Сообщение noLogicOnlyWar »

Не норм. App layer об инфраструктуре ничего знать не должен.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: command bus !== ООП?

Сообщение zelenin »

вики: инфраструктура - комплекс взаимосвязанных обслуживающих структур или объектов, составляющих и обеспечивающих основу функционирования системы

ComamndHandler - это сущность слоя Application. Почему она в инфре?
В инфре только реализации, и то не все. Часть функционала надо выносить в модули.
Вот у тебя есть в приложении модули Blog, Shop, Api. Все три модуля используют шину, шина - сущность уровня приложения, ее надо вынести в модуль MessageBus и создавать в модуле Application, который будет ядром приложения, объединяющим модули. В разных модулях понадобится HttpClient. Надо вынести в модуль HttpClient. Причем модуль может состоять только из одной фабрики, создающей например инстанс GuzzleClient. Можно написать свой интерфейс для клиента, адаптер клиента над газзлом и фабрику. Можно свой клиент написать на чем угодно.
Bio man
Сообщения: 609
Зарегистрирован: 2013.07.22, 10:40

Re: command bus !== ООП?

Сообщение Bio man »

zelenin писал(а): 2018.01.19, 12:20 ComamndHandler - это сущность слоя Application. Почему она в инфре?
Она в app. В инфре фабрики создающие хендлеры.

Получается, фабрики оставить в инфраструктуре, а Aware интерфейсы (которые используются командами и инфраструктурными фабриками) в приложении?
Bio man
Сообщения: 609
Зарегистрирован: 2013.07.22, 10:40

Re: command bus !== ООП?

Сообщение Bio man »

Что бы было наглядно, структура всего на данный момент
Изображение
Ответить