首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >命令+ CommandHandler和服务有什么区别?

命令+ CommandHandler和服务有什么区别?
EN

Stack Overflow用户
提问于 2014-06-29 17:40:02
回答 2查看 14.3K关注 0票数 52

我一直在阅读有关使用Command对象来表示我们的域公开的用例,以及Command Handler对象来处理这些命令的内容。

例如:

  • RegisterUserCommand
  • RegisterUserCommandHandler

但它看起来与拥有RegisterUserService完全相同,其中命令对象将表示registerUser()方法的参数。

当然,如果该方法有太多的参数,我将最终创建一个对象来包装它们,该对象将与RegisterUserCommand相同。

那么,为什么要用不同的模式来表示相同的东西呢?服务是广泛存在的,而不是命令(根据我的经验);这里我缺少的区别是什么?简而言之,为什么我要使用一个而不是另一个呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-30 00:30:48

拥有命令为您提供了良好的旧命令模式的好处:

  • 您可以使用用于执行撤消的命令对对象(例如UI元素)进行参数化您可以存储命令并在以后执行它,例如,在队列或事务日志
  • 中您可以跟踪执行了哪些命令,从而为实现

奠定了基础

如果您的服务很大,每个服务都有许多复杂的方法(如果这些方法不复杂,您可能不应该使用DDD或CQRS),那么将每个方法移动到命令处理程序中可能会通过使应用程序更具可组合性、更易于测试等来改进应用程序。毫无疑问,直接从大型服务重构到命令/命令处理程序的人通常认为这是后一种模式的好处。但您可以通过将大型服务分解为较小的服务来获得相同的好处(正如示例中的特定服务所建议的那样),因此严格地说,这并不是服务和命令/命令处理程序之间的区别。

票数 33
EN

Stack Overflow用户

发布于 2014-06-30 00:41:15

我认为你完全正确地质疑这两个概念在上下文中似乎是相似的。这可能值得回去考虑,实际上,它们的目的是什么。

DDD服务

在域驱动设计中,有不同类型的服务,例如应用程序服务(通常是UI服务)、基础架构服务和域服务。

Jimmy Bogard does an excellent job of explaining these

简而言之:

域服务

域服务的工作是执行通常不适合某个实体的功能。当您的一项功能需要各种不同的

实体(聚合/值对象)。举个例子:要计算抵押贷款可能花费多少的估计,你需要买家的收入/就业的详细信息。您可能需要买方的信用记录,最后,您可能需要有关该建筑物的抵押贷款正在考虑的信息。

代码语言:javascript
复制
pricingService.CalculateMortageEstimate(BuyerIncomingDetails bid, BuyerCreditHistory bch, BuildingOverview bo)

应用程序服务

例如,作为UI的一部分使用的服务。

基础架构服务

倾向于与外部资源(电子邮件发件人、文件系统、xml文件、ftp等)通信的服务

命令/ CommandHandlers (CQRS)

命令查询责任分离。就像罐头上写的那样;分离:

针对data source

  • Modifying运行查询的
  1. (通过命令) data

使用CQRS并不总是正确的选择,但根据我的经验,当他们的数据分布在多个数据源时,人们倾向于使用它。

因此,通过这些命令,您可以显式地请求执行一个工作单元(不要与UnitOfWork模式混淆),例如AddFraudRecordCommand或UpdateNoteCommand。

对DDD服务和CQRS命令之间的区别稍作更新。我要注意以下几点:

  1. 我甚至需要命令/ CommandHandlers吗?我得到了什么,我应该直接转到我的命令处理程序的services?
  2. The工作是处理我的命令的逻辑(一个命令是一个非常具体的请求)。虽然DDD服务有不同的任务(域服务:协调多个实体的功能,基础架构服务:与外部服务协作,例如电子邮件)
  3. 可能会这样想: CommandHandler作业-执行代码以运行特定命令(这可能包括使用多个服务)。服务作业-取决于服务类型。

这不是最好的例子,但我希望它能对我想要说的话有所启发:

代码语言:javascript
复制
public class CalculateFraudProbabilityCommandHandler : CommandHandler<CalculateFraudProbabilityCommand>
{
         IFraudService _fraudService;
         IEmailNotifier _notifier;
         ICustomerRepository _customerRepo;


  public CalculateFraudProbabilityCommandHandler(ICustomerRepository customerRepo, IFraudService fraudService, IEmailNotifier notifier) 
  {     
        _fraudService = fraudService; //Domain Service  
        _notifier = notifier;         //Infrastructure Service  
        _customerRepo = customerRepo; //Repository
  }

 //Execute Command
 public void Execute(CalculateFraudProbabilityCommand command) {

     Customer customer = _customerRepository.GetById(command.CustomerId);
     FraudHistory fraudHistory = _fraudService.RetrieveFraudHistory(customer);

     //any fraud recently? if so, let someone know!
      if(fraudHistory.FraudSince(DateTime.Now.AddYear(-1)) {
           _notifier.SendEmail(_fraudService.BuildFraudWarningEmail(customer,      fraudHistory));
      }     

   }

}
票数 29
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24474859

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档