CQRS – Why Separate CommandHandler with Handle() Instead of Handling Method in Command Itself

Architectureccqrsdesign-patterns

I have a part of CQRS pattern implemented using S#arp Architecture like this:

public class MyCommand
{
    public CustomerId { get; set; }
    
    // some other fields
}

public class MyCommandHandler<MyCommand> : ICommandHandler<MyCommand, CommandResult>
{
    Handle(MyCommand command)
    {
        // some code for saving Customer entity

        return CommandResult.Success;
    }
}

I wonder why not just have class Command containing both data and handling method? Is it a kind of testability benefit, where you need to test command handling logic separately from command properties? Or is it some frequent business requirement, where you need to have one command handled by different implementations of ICommandHandler<MyCommand, CommandResult>?

UPDATE:

Looking at it after 6 years, I say making a handler class for each command type is definitely an overkill with a lot of syntactic noise. Nowadays I would have a single class to handle a bunch of commands related to the same topic (akin to Sum Types in more functional languages). If each of them requires a gigantic handler, than they should be split into simpler steps, managed by finer grained commands. Or use a different pattern altogether.

Best Answer

Funny, this question just reminded me of exactly same conversation I had with one of our engineers about communications library I was working on.

Instead of commands, I had Request classes and then I had RequestHandlers. The design was very much like what you are describing. I think part of the confusion that you have is that you see the English word "command", and instantly think "verb, action... etc".

But in this design, think of Command (or Request) as a letter. Or for those that don't know what a postal service is, think e-mail. It is simply content, decoupled from how that content should be acted upon.

Why would you do this? In most simple cases, of Command Pattern there is no reason and you could have this class perform work directly. However, doing the decoupling as in your design makes sense if your action/command/request must travel some distance. For example, across, sockets or pipes, or between domain and infrastructure. Or maybe in your architecture your commands need to be persistent (e.g. command handler can do 1 command at a time, due to some system events, 200 commands arrives and after first 40 process gets shutdown). In that case, having a simple message-only class it becomes very simple to serialize just the message part into JSON/XML/binary/whatever and pass it down the pipeline until its command handler is ready to process it.

Another advantage of decoupling Command from CommandHandler is that now you have the option of parallel inheritance hierarchy. For example, all your commands could derive from a base command class that supports serialization. And maybe you have 4 out of 20 command handlers that have a lot of similarity, now you can derive those from the came handler base class. If you were to have data and command handling in one class, this type of relationship would quickly spiral out of control.

Another example for the decoupling would be if your command required very little input (e.g. 2 integers and a string) yet its handling logic was complex enough where you would want to store data in the intermediate member variables. If you queue up 50 commands, you don't want to allocate memory for all that intermediate storage, so you separate Command from CommandHandler. Now you queue up 50 light-weight data structures and more complex data storage is allocated only once (or N times if you have N handlers) by the CommandHandler that is processing the commands.