DDD - Сервис или обработчик в подписчике? - PullRequest
0 голосов
/ 30 ноября 2018

У меня есть проект DDD, и я не знаю, лучше ли использовать Handler или Service непосредственно в подписчиках.

Позвольте мне уточнить;Предполагая, что

  • Командный объект должен получать на вход только тип примитива
  • Обработчик получает команду и преобразует примитивные данные в модель предметной области

Мой вопрос: еслиЯ поднимаю событие домена, подписчик должен запустить службу или другой обработчик команд?

Позвольте мне привести пример:

class CommandOne{    
    public function __construct(string $stuff){
        $this->stuff = $stuff;
    }
    public function getStuff(){
        return $this->stuff;
    }
}

// Handler, called from a ControllerAction
class HandlerCommandOne{

    public function __construct(StuffRepository $stuffRepository, 
                                SomeService $service){
        $this->service = $service;
        $this->stuffRepository = $stuffRepository;
    }

    public function handle(CommandOne $command){

        $stuff = $command->getStuff();
        $stuffModel = $this->stuffRepository->find($stuff);

        //Some Business Logic
        $this->service->doBusinessActivity();
        $this->anotherService->doAnotherBusinessActivity();

        // If I want that subscriber will use  Service , I inject a model in event constructor
        $this->dispatcher->dispatch(StuffEvent::NAME,new StuffEvent($stuffModel));

        // If I want that subscriber will use a CommandHandler , I inject primitives in event constructor
        $this->dispatcher->dispatch(StuffEvent::NAME,new StuffEvent($stuffModel->getId(),$stuffModel->getName()));
    }
}


class SomeSubscriberWithHandler{    
    public function __construct(CommandHandler $handler) {
        $this->handler = $handler;        
    }
    public function OnStuffEvent($event){                    
        $command = new SomeOtherCommand($event->getId(), $event->getName());
        $this->handler->handle($command); // Handle will handle logic calling other services ...
    }
}

class SomeSubscriberWithService{        
    public function __construct(Service $service) {
        $this->service = $service;
    }
    public function OnStuffEvent($event){
        $model = $event->getModel();
        $this->service->doLogic($model);
    }
}

Я вижу за и против;Я знаю, что в DDD лучше создать событие с данными PRIMITIVES, потому что событие может быть перехвачено вне ограниченного контекста, где ваша модель не может иметь никакого значения.

Но если я использую примитив, мне нужно вызватьхранилище каждый раз, когда мне нужна информация от сущности ....

Например, подписчик должен уведомить о создании новой модели, отправив электронные письма;Вы бы создали обработчик в подписчиках или услугах напрямую?

Заранее спасибо

1 Ответ

0 голосов
/ 30 ноября 2018

Учитывая, что мы реализуем связь между ограниченным контекстом (BC) с помощью очереди сообщений (MQ), вышестоящий BC должен опубликовать событие домена, переведя его в сообщение, которое будет отправлено в MQ.

С другой стороны, подписчик в нисходящем BC будет слушателем, который преобразует сообщение, полученное от MQ, в команду и запускает обработчик команд.

Слушатель является инфраструктурой, поскольку он имеет дело с технологией(MQ).Он находится за пределами приложения, принимает сообщение и вызывает службу приложения (или обработчик команд).

Именно так это делается в примерах из Красной книги (Реализация доменного дизайна).Вы можете посмотреть их на https://github.com/VaughnVernon/IDDD_Samples

...