Leveraging command pattern with Spring
Tags: java, spring, designpatterns
Published: 2020-07-25 11:10:05

## Intro

Every Java developer is either using Spring or at least heard of it, especially about Dependency Injection mechanism it provides. With a simple annotation 
```java
@Component
public class MyComponent {}
```
we can create a bean and then inject it into our class 
```java
@Autowired
private MyComponent component;
```
and Spring will handle the rest. The caveat to this, is that when extending some common interface, we need to tell specifically which instance we want to inject or mark one of the implementations as `@Primary`. 

Or do we ?

## The Trick

There is a simple way to inject ALL of our implementations into the class, and it looks like this:
```java
 @Autowired
private Map<String, CommonInterface> interfacesMap;
```

It's a super simple mechanism, which allows us to create a map of instances of our CommonInterface where the class name is the key. 

## The Leverage

We can leverage this to create easy to use Command Pattern implementation. For that we will need 4 interfaces or abstract classes:
* `Command`
* `CommandResult`
* `CommandExecutor`
* `CommandDispatcher`

`Command` and `CommandResult` will be only used to pass parameters/request and to receive the answer/response respectively. The `CommandExecutor` will use generics to bind it to `Command`:
```java
public interface CommandExecutor<C extends Command, R extends CommandResult> {
    R execute(C command);
}
```

Now the core of this solution - the `CommandDispatcher`. It will be responsible for triggering the `execute` method of `CommandExecutor` based on the `Command` type passed to it. The abstract class will look like this:

```java
public abstract class CommandDispatcher {
    protected Map<Class, CommandExecutor> preparedMap = new HashMap<>();

    public <C extends Command, R extends CommandResult> R dispatch(C command) {
        return (R) preparedMap.get(command.getClass()).execute(command);
    }
}
```

In the concrete implementation of the executor, using mechanism shown at the beginning we can inject all of our `CommandExecutors` into the class and using reflections we can bind `Executor` to the `Command`:

```java
@Service
public class SpringCommandDispatcher extends CommandDispatcher {
    private final Map<String, CommandExecutor> rawMap;

    public SpringCommandDispatcher(Map<String, CommandExecutor> rawMap) {
        this.rawMap = rawMap;
    }

    @PostConstruct
    private void setUp() {
        if (rawMap != null && !rawMap.isEmpty()) {
            for (CommandExecutor commandExecutor : rawMap.values()) {
                Type command = ((ParameterizedType)commandExecutor.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0];
                preparedMap.put((Class) command, commandExecutor);
            }
        }
    }
}
```

And that's it. To dispatch some command we simply inject the `CommandDispatcher` and use it like this:
```java
SomeCommandResult result = commmandDispatcher.dispatch(new SomeCommand());
```

The major advantage of using Command Pattern this way is separatation of the 'business' logic from the `Command`, thanks to which we can have different implementations of the same `Command` for different versions of our application. 


## Summary

Working example of this can be found [in my github](https://github.com/DigitalCrafting/basic-web-app-showcase). 

This was my first ever post about what I know so I hope You enjoyed it and that it will come handy in Your projects 😊