Подтвердить что ты не робот

В чем разница между Command + CommandHandler и службой?

Я читал об использовании объектов Command для представления случаев, которые предоставляет наш домен, и объектов Command Handler для обработки этих команд.

Например:

  • RegisterUserCommand
  • RegisterUserCommandHandler

Но он выглядит точно так же, как с RegisterUserService, где объект команды будет представлять параметры для метода registerUser().

И, конечно, если у метода было слишком много параметров, я бы создал объект для их переноса, и этот объект будет таким же, как и RegisterUserCommand.

Итак, почему у другого шаблона есть одно и то же? Услуги широко распространены, а не Команды (по моему опыту); в чем разница, что я пропала? Короче говоря, почему я должен использовать один, а не другой?

4b9b3361

Ответ 1

Наличие команд дает вам преимущества старого старого шаблона команды:

  • вы можете параметризовать объект, например. элемент пользовательского интерфейса, с командой для выполнения
  • вы можете сохранить команду и выполнить ее позже, например. в очереди или в журнале транзакций
  • вы можете отслеживать, какие команды вы выполнили, давая вам основание для выполнения отмены

Если ваши услуги были большими, каждый из которых имеет множество сложных методов (и если методы не были сложными, вам, вероятно, не следует использовать DDD или CQRS), то перемещение каждого метода в обработчик команд может улучшить ваше приложение, сделав его более сложный, простой в тестировании и т.д. Несомненно, это обычное явление для людей, которые реорганизуют прямо из больших служб в Commands/Command Handlers, рассматривая это как преимущество последнего шаблона. Но вы можете получить ту же выгоду, разложив большие сервисы на более мелкие (как это предлагает конкретная служба в вашем примере), так что строго говоря, это не разница между службами и командами/обработчиками команд.

Ответ 2

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

Службы DDD

В Domain Driven Design существуют различные виды услуг например Службы приложений (обычно службы пользовательского интерфейса), службы инфраструктуры и доменные службы.

Джимми Богард отлично справляется с этим

В двух словах:

Доменные службы

Задача служб домена заключается в выполнении функций, которые обычно не подходят для одного объекта. Подумайте о том, как использовать службу домена, когда у вас есть функциональность, требующая разнообразных объекты (объекты совокупности/ценности). Например, возможно: чтобы рассчитать оценку того, сколько может стоить закладная, вам требуется подробная информация о доходах/занятости покупателей. Вы можете потребовать кредитную историю покупателей, и, наконец, вам может понадобиться информация о здании, которое рассматривает ипотечный кредит.

pricingService.CalculateMortageEstimate(BuyerIncomingDetails bid, BuyerCreditHistory bch, BuildingOverview bo)

Службы приложений

Например, возможно, сервисы, используемые как часть пользовательского интерфейса.

Услуги инфраструктуры

Службы, которые имеют тенденцию связываться с внешними ресурсами (отправители электронной почты, файловые системы, xml файлы, ftp и т.д.)

Command/CommandHandlers (CQRS)

Сегментация ответных запросов командного запроса. Как говорится на олове; разделение:

  • выполнение запросов к источнику данных
  • Изменение (через команды) ваших данных

использование CQRS не всегда является правильным вариантом, но, по моему опыту, люди склонны использовать его, когда их данные нарушены в нескольких источниках данных.

Таким образом, с помощью команд вы явно запрашиваете единицу работы (не путать с шаблоном UnitOfWork), которая должна быть выполнена, например. AddFraudRecordCommand или UpdateNoteCommand.


С этим небольшим освещением о различиях между службами DDD и командами CQRS. Я хотел бы отметить следующие вещи:

  • Мне даже нужны Command/CommandHandlers? Что я набираю, должен ли я просто перейти непосредственно к услугам?

  • Работа моего обработчика команд - это обработка логики моей команды (команда - очень специфический запрос). В то время как службы DDD имеют разные задания (Сервисы домена: координация функций нескольких объектов, Infrastructure Services: сотрудничество с внешними службами, например, электронная почта)

  • Возможно, подумайте об этом так: CommandHandler Job - выполнить код для запуска конкретной команды (это может включать использование нескольких служб). Сервисное задание - в зависимости от типа обслуживания.

Не лучший пример, но я надеюсь, что он озарит некоторый свет на том, что я пытаюсь сказать:

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));
      }     

   }

}