There are two questions in the question with multiple answers :)
The first question is should a command return an error state?
There is no clear answer for every program every time you apply the pattern you have to think about it again.
One of the things you need to think about is:
- Am I adding more coupling to many commands and the clients for only some specific error cases?
In the worst case you have many commands that don't care about errors but one or two commands do something that is important for the client to know if it worked. You now add checked Exceptions to the Interface and so every client and every Command are bound to do error handling and are coupled to the Exception. If you have a client that only deals with commands that are not throwing the exceptions you have a big overhead in your code.
This is a thing that you don't want to have. So you can either move the commands that need error handling out of the command structure because they seem to be different from the other commands, or if your language allows it you can add runtime exceptions that are only handled by the clients that care and thrown by the commands that need to throw them.
The other extreme is that every command can fail and the client has a consistent way of handling the errors this means that the errors doesn't depend on the specific command. The client does not have to know what kind of command failed it can handle every error in the same way. Now you could have the interface of the command return an error state and the client can deal with the errors. But dealing with the errors shouldn't depend on the kind of the command for the client.
The second question is: Should a command have a state?
There are architectures where a command needs a state and some where they don't need a state.
Some possibilities to decide this:
- If you want to have a undo for your command the commands need to have a state.
If the commands are only used for hiding a way a function that works on a small set of parameters and the outcomes only depends on the same of the command like the state pattern there is no need for a state and you can use the same object over and over.
If you use the command to communicate between threads and you want to transfer data from one thread to another the command needs a state.
- ... If there is something you think should be in this list leave a comment.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…