Let’s say I’m writing a bot for a chat (discord, telegram, whatever). The bot can handle chat commands (e.g. !join tells it to join a voice channel on the server).
So somewhere in my code I’d have to parse the command, and I’ll have something like
String userMessage = getTheMessageTextSomehow();
// Do something with the message.
I’d like to have a Command class for every one of my commands, and every command would implement a execute() method.
My question is: what’s the best practice to create those command objects?
The easiest way would be to have a large CommandFactory or whatever class somwhere, that would be like
if(message.equals(JOIN_MESSAGE) {
return new JoinCommand();
}
if(message.equals(LEAVE_MESSAGE){
return new LeaveCommand();
}
//etc...
That looks like a bad practice and code smell to me.
Is there a better way to do it?
3
Answers
You might want to rely on a
Map
ofCommand
s.I’ll make it clear that for this usecase, using the
Function
orSupplier
, or whatever standard functional interface is not idiomatic at all. Avoid it.We can start by building a
Command
interfaceOr if you need to accept an argument
Which will have the required implementations
And so on.
You’ll now need to store those definitions in a
key
(the command) –value
(the implementation) data structure. AMap
is perfect for that.As your command definition will be a
String
, thenThe usage is pretty simple
Or if you’ll have to accept an argument
You’ll also notice I used
NOOP_COMMAND
, that’s just a no-op implementation forCommand
to avoid dealing withnull
. It might be, or it might be not, appropriate.If you’re on
Java 9+
, theMap
could also be created usingUsually, it is implemented via mapping. It would be much clearer and readable to implement this with simple
Map
.For example:
And its usage:
Moreover, you can define creation strategies (factories) since Java 8 if you need to construct commands depending on some parameters.
And its usage:
Hello You try Switch Case statement for it, it’s easy to understand and in future if you have any changes then it’s easy to update the code.