我一直在阅读有关使用Command对象来表示我们的域公开的用例,以及Command Handler对象来处理这些命令的内容。
例如:
RegisterUserCommand
RegisterUserCommandHandler
但它看起来与拥有RegisterUserService
完全相同,其中命令对象将表示registerUser()
方法的参数。
当然,如果该方法有太多的参数,我将最终创建一个对象来包装它们,该对象将与RegisterUserCommand
相同。
那么,为什么要用不同的模式来表示相同的东西呢?服务是广泛存在的,而不是命令(根据我的经验);这里我缺少的区别是什么?简而言之,为什么我要使用一个而不是另一个呢?
发布于 2014-06-30 00:30:48
拥有命令为您提供了良好的旧命令模式的好处:
奠定了基础
如果您的服务很大,每个服务都有许多复杂的方法(如果这些方法不复杂,您可能不应该使用DDD或CQRS),那么将每个方法移动到命令处理程序中可能会通过使应用程序更具可组合性、更易于测试等来改进应用程序。毫无疑问,直接从大型服务重构到命令/命令处理程序的人通常认为这是后一种模式的好处。但您可以通过将大型服务分解为较小的服务来获得相同的好处(正如示例中的特定服务所建议的那样),因此严格地说,这并不是服务和命令/命令处理程序之间的区别。
发布于 2014-06-30 00:41:15
我认为你完全正确地质疑这两个概念在上下文中似乎是相似的。这可能值得回去考虑,实际上,它们的目的是什么。
DDD服务
在域驱动设计中,有不同类型的服务,例如应用程序服务(通常是UI服务)、基础架构服务和域服务。
Jimmy Bogard does an excellent job of explaining these
简而言之:
域服务
域服务的工作是执行通常不适合某个实体的功能。当您的一项功能需要各种不同的
实体(聚合/值对象)。举个例子:要计算抵押贷款可能花费多少的估计,你需要买家的收入/就业的详细信息。您可能需要买方的信用记录,最后,您可能需要有关该建筑物的抵押贷款正在考虑的信息。
pricingService.CalculateMortageEstimate(BuyerIncomingDetails bid, BuyerCreditHistory bch, BuildingOverview bo)
应用程序服务
例如,作为UI的一部分使用的服务。
基础架构服务
倾向于与外部资源(电子邮件发件人、文件系统、xml文件、ftp等)通信的服务
命令/ CommandHandlers (CQRS)
命令查询责任分离。就像罐头上写的那样;分离:
针对data source
使用CQRS并不总是正确的选择,但根据我的经验,当他们的数据分布在多个数据源时,人们倾向于使用它。
因此,通过这些命令,您可以显式地请求执行一个工作单元(不要与UnitOfWork模式混淆),例如AddFraudRecordCommand或UpdateNoteCommand。
对DDD服务和CQRS命令之间的区别稍作更新。我要注意以下几点:
这不是最好的例子,但我希望它能对我想要说的话有所启发:
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));
}
}
}
https://stackoverflow.com/questions/24474859
复制相似问题