Sunday, January 27, 2013

Organizing commands and queries

In the last few posts I settled on an architecture for handling commands and queries. A byproduct of the described approach, is that your codebase quickly racks up plentiful little classes; a class to hold data, and a handler to act on that data, for each use case.

There are a few ways you can go at organizing things.

Everything in one location

When there is very little going on in your application, you can just dump everything in one location without getting hurt too much.




Folder per functionality

When your application grows, and the coherency between different use cases are obvious, you can just use folders - and corresponding namespaces, to organize your commands and queries, and to draw their functional boundaries. Uncle Bob and Mark Needham have sold me on structuring my code based on functionality instead of technical concepts.


Keeping each commandhandler in a separate class is especially interesting when they are rather bulky and contain a good amount of logic. You can think of each class as a little piece of functionality in itself. Take a look at the RavenDB codebase to get an idea of what that could look like.

It also feels like this way tends to bring your code closer to the Solution Explorer; just one double-click and you are looking at your implementation; no scrolling or searching between method definitions necessary. Maybe the problem is now just shifted a level higher in the hierarchy though.

Composing a service class

You can also opt to group commandhandler implementations in one service class. This variation might make more sense when your implementations are rather skinny, and don't do a whole lot but translating and forwarding your invocation.
public class SubscriptionService : 
        ICommandHandler<SubscribeCommand>,
        ICommandHandler<UnsubscribeCommand>
{
    public void Handle(SubscibeCommand command)
    {
        throw new NotImplementedException();
    }

    public void Handle(UnsubscribeCommand command)
    {
        throw new NotImplementedException();
    }
}
Use the hints your dependency graph gives you to find a composition that makes sense.

How do you go at organizing commands and queries?

4 comments:

  1. Foldernames and corresponding namespaces I agree on. But commands and handlers live in their respective subfolders, not grouped by functional boundaries. Only if projects grow large functional boundaries find their way to a seperate assembly.

    I have found working with intellisense easier this way, like: companyname.handler.functionalboundaryhandler, or in case of larger solutions, companyname.functionalboundary.handler.functionalboundaryhandler

    ReplyDelete
    Replies
    1. I think the advantages gained by putting things that belong together functionally outweigh the IntelliSense argument: no more cognitive overload, you can focus on one functionality at a time... This blog post describes the advantages in detail: http://www.markhneedham.com/blog/2012/02/20/coding-packaging-by-vertical-slice/

      Delete
    2. Well, you can't really argue with Uncle Bob Martin now can you :).

      The cognitive load for myself would probably be the same, so that would be up to other team members to decide. Under these different cognitive loads the intellisense argument is probably moot anyway.

      The point of micro services is a good one. But in that scheme I still have the argument of falling back on separate assemblies.

      Anyway, nice one to think about and to keep in mind when starting the next project.

      Delete
  2. Well, I have a project with 100+ commands in it. We group them into namespaces based on their feature, i.e. "Invoices", "Offers", etc. I haven't identified any problem with this style of grouping so for anything larger than a few commands, I would go with this approach.

    ReplyDelete