13

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>?

14

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.

  • The point is, that in this context, the command/request is not remote/persisted/etc.. It is handled directly. And I can't see how separating the two would help with inheritance. It would actually make it harder. The last paragraph is also kind of miss. Object creation is not expensive operation and 50 commands is neglectable number. – Euphoric Jan 10 '14 at 22:47
  • @Euphoric: how do you know what the context is? Unless S#arp Architecture is something special, all I see is a couple of class declarations and you have no idea how they are used in the rest of the application. If you don't like the numbers I chose like 50, choose something like 50 per sec. If that's not enough, pick 1000 per sec. I was just trying to provide examples. Or you don't think in this context he'll have that many commands? – DXM Jan 10 '14 at 22:54
  • For example, the exact structure is seen here weblogs.asp.net/shijuvarghese/archive/2011/10/18/… . And nowhere there it says what you said. And about the speed, the problem is you used 'performance' argument without profiling. If you do have requirements for such throughtput, you are not going to use generic architecture but build something more specialized. – Euphoric Jan 10 '14 at 22:59
  • 1
    Let me see if this was your last point: OP asked for examples, and I should have said, for example, first you design the simple way and your application works, then you scale up and you extend places where you use command pattern, then you go live and you get 10,000 machines talking to your server and your server still uses your original architecture, then you profile and identify the issue, and then you could separate command data from command handling, but only after you profile. Would it really make you happier if I included all that in the answer? He asked for an example, I gave him one. – DXM Jan 10 '14 at 23:04
  • ... so I just glanced through that blog post you posted and it does seem to align with what I wrote: separate them if your command has to travel some distance. In the blog he seems to be referring to a command bus which is basically just another pipe, socket, message queue, esb... etc – DXM Jan 10 '14 at 23:07
2

Normal command pattern is about having the data and behavior in single class. This kind of 'Command/Handler pattern' is slightly different. The only advantage compared to the normal pattern is added advantage of not having your command depend on frameworks. For example, your command might need DB access so it has to have some kind of DB context or session, meaning it is dependent on frameworks. But this command might be part of your domain, so you don't want it to depend on frameworks according to Dependency Inversion Principle. Separating the input and output parameters from the behavior and having some dispatcher to wire them up can fix this.

On the other hand, you will loose advantage of both inheritance and composition of commands. Which I think is it's true power.

Also, minor nitpick. Just because it has Command in name doesn't make it part of CQRS. That is about something much more fundamental. This kind of structure can serve both as command and as a query even at the same time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.