DDD-服务或订阅服务器中的处理程序?

时间:2018-11-30 11:37:11

标签: service domain-driven-design

我有一个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 :(得分:0)

鉴于我们通过消息队列(MQ)实现了边界上下文(BC)之间的通信,上游BC将通过将域事件转换为将发送到MQ的消息来发布域事件。

另一方面,下游BC中的订户将是一个侦听器,它将将从MQ接收的消息转换为命令,然后运行命令处理程序。

侦听器具有基础结构,因为它处理技术(MQ)。它在应用程序外部,接收消息并调用应用程序服务(或命令处理程序)。

这是在红皮书(实施域驱动设计)的示例中完成的。您可以在https://github.com/VaughnVernon/IDDD_Samples

上查看他们