Command Handler Pattern in Java EE
I named it command-handler pattern, but actually it’s modified command pattern. In classic command pattern, we have Command class that handles action on a given object. You can see it in Switch example. First difference is decoupling of command and action execution. It also simplifies segregating read and write queries/commands (aka. CQRS). In command handler pattern, commands are fairly simple and often consist of data that is needed to execute action. Such command can be send via HTTP connection or taken from queue. In Java, they are often plain objects. Each command has it’s handler, that executes certain logic, for example modifies or reads and return some data. Aside of this, we have CommandDispacher/CommandGateway class which is dispatching commands to handler classes. If we want to add new command we create Command and handler then we need to register them in CommandDispacher class.
Command handler pattern advantages
You can check my JavaEE implementation of this pattern available on GitHub: Command Pattern in JavaEE, We will be using it in the next article, but you can check it for reference.
Firstly, let’s start with some of the features of this approach that are often mentioned on different forums and blog posts:
- It decouples invoker and receiver of the command by intermediate executor.
- Encourages to implement classes compliant with SRP(Single Responsibility Principle).
- Simplifies adding new features.
- Simplifies adding functionality to record and undo commands.
- Simplifies adding decorators, validators, profilers that need to execute for every command.
- Allows to create macro commands.
What is decoupling?
@Path("/productcart") public class ProductResource { @Inject private AddToCartHandler handler; @POST @Path("/add") @Consumes(MediaType.APPLICATION_JSON) public Response addToCart(AddToCartCommand command) { handler.handle(command); return Response.ok().build(); } }
At first glance it’s OK. We just call AddToCartHandler directly. Coupling of invoker and receiver cannot be omitted. The question is why use command-handler pattern? But let’s think on architecture level. Let’s say that we want our API to be independent, cause project grow large and our front-end team will handle Rest API for us. In short, we want API to be in separate jar file and let’s call it Command Invoker. We also added a DTO package with plain Java objects used by both teams.
Below we see dependency diagram. Our core package uses DTO objects and Command Invoker package. Command Invoker package needs to use our core package, cause we call handler directly. Imminently we see a cycle in graph, which indicates that when Core package change, then Command Invoker package needs to change.
At this level we see coupling. The other team needs to know about changes in handlers package, and we change them often, maybe rewrite them totally. We produced another classic monolith. If we change something in core logic (aka. handlers) then we need to change it in client. This is the place where this pattern shines. Let’s see dependency diagram with command handler pattern applied:
In above diagram we doesn’t see cycle anymore. Our Core application uses Command Dispacher framework, Command Invoker and DTOs. Command Invoker does not use Core and can be developed independently. It only uses dispatcher framework and DTO’s. Notice that Core Application needs to use Command Invoker, let’s say Rest API, because it wont work without it. If we want to add new command, we just need to add it in DTO’s and let the other team know that we need newer version of their package, that includes new API endpoint. They does not need to know how we handle this command.
In addition Core Application become stable package. I will post article about architecture and dependencies of modules/classes in near future. For now, we see that decoupling is really an advantage of command handler pattern.
Thanks for reading.
Leave a comment below 🙂
Nice Article … Keep up the good work