What is the difference between Command + CommandHandler and Service?

Design PatternsDomain Driven-DesignCqrsCommand Pattern

Design Patterns Problem Overview


I have been reading about using Command objects to represent use cases that our domain exposes, and Command Handler objects to process those commands.

For example:

  • RegisterUserCommand
  • RegisterUserCommandHandler

But it looks exactly the same as having a RegisterUserService, where the command object would represent the parameters to the registerUser() method.

And of course, if the method had too many parameters, I would end up creating an object to wrap them and that object would be the same as the RegisterUserCommand.

So why have a different pattern to represent the same thing? Services are widespread, not Commands (from my experience); what is the difference here that I am missing? In short, why would I use one rather than the other?

Design Patterns Solutions


Solution 1 - Design Patterns

Having Commands gives you the benefits of the good old Command pattern:

  • you can parameterize an object, e.g. a UI element, with a Command to perform
  • you can store a Command and execute it later, e.g. in a queue or a transaction log
  • you can track which Commands you executed, giving you a foundation for implementing undo

If your services were large, each with many complex methods (and if the methods weren't complex you probably shouldn't be using DDD or CQRS), then moving each method into a Command Handler might improve your application by making it more composable, easier to test, etc. No doubt it is common for people who refactor straight from big services to Commands/Command Handlers to regard this as a benefit of the latter pattern. But you could get the same benefit by decomposing large services into smaller ones (as suggested by the very specific service in your example), so strictly speaking that isn't a difference between services and Commands/Command Handlers.

Solution 2 - Design Patterns

I think you're completely right to question that these two concepts seem to be similar in context. It’s probably worth going back and considering, practically, what they are intended for.

DDD Services

In Domain Driven Design, there are different types of services e.g. Application Services (commonly UI services), Infrastructure Services and Domain Services.

Jimmy Bogard does an excellent job of explaining these

In a nutshell:

Domain Services

The job of the domain services is to execute functionality that typically doesn't suit for one entity. Consider using a domain service when you have a piece of functionality that requires a variety of
entities (aggregate / value objects). An example maybe: to calculate an estimate on how much a mortgage may cost, you require the detail on the buyer’s income / employment. You may require the buyer’s credit history and finally you may need information on the building that the mortgage is being consider for.

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

Application Services

An example maybe services used as part of the UI.

Infrastructure Services

Services that tend to communicate with external resources (email senders, file systems, xml files, ftp etc...)

Command / CommandHandlers (CQRS)

Command Query Responsibility Segregation. As it says on the tin; a separation of:

  1. running queries against your data source
  2. Modifying (via commands) your data

using CQRS isn't always the right option but in my experience, people tend to use it when their data is distributed across multiple data sources.

So with the commands, you are explicitly asking for a unit of work (not to be confused with the UnitOfWork pattern) to be executed e.g. AddFraudRecordCommand or UpdateNoteCommand.


With that little refreshment on the differences between DDD services and CQRS commands. I would note the following things:

  1. Do I even need Command / CommandHandlers? What am I gaining, should I just go directly to the services?

  2. The job of my Command Handler is to handle the logic of my command (a Command being a very specific Request). Whereas the DDD services have different jobs (Domain Services: coordinate functionality of multiple entities, Infrastructure Services: collaborate with external services e.g. email)

  3. Maybe think of it like this: CommandHandler Job – execute the code to run the specific command (this may include using multiple services). Service Job – Depending on what type of service it is.

Not the best example, but I’m hoping it shines some light on what I’m trying to say:

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

   }

}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMatthieu NapoliView Question on Stackoverflow
Solution 1 - Design PatternsDave SchweisguthView Answer on Stackoverflow
Solution 2 - Design PatternsMikeView Answer on Stackoverflow