Design patterns are a must know for any software developer. They are important not just because they give developers a set of tools to overcome common problems encountered while developing software, but the also give developers a common language with which to communicate with.
Classic ‘Design patterns’ are grouped in three different categories: Creational, Structural and Behavioral, as outlined in the book ‘Design Patterns: Elements of Reusable Object-Oriented Software’ by the Gang of Four.
The book is very good at categorizing each pattern and aside from the name, it outlines the problem, the solution and the consequences for each pattern.
The ‘Command’ pattern is a behavioral pattern.
“Behavioral patterns are concerned with algorithms and the assignment of responsibilities between objects. Behavioral patterns describe not just patterns of objects or classes but also the patterns of communication between them. These patterns characterize complex control flow…”
Design Patterns: Elements of Reusable Object-Oriented Software
The ‘Command’ pattern in particular encapsulates all the actions and parameters needed to carry out the work. When looking at ‘Design Patterns’ by the Gang of Four, the pattern mentions four terms, which are command, receiver, invoker and client.
Each actor in this design pattern is responsible for the following:
- Command: Declares and interface for executing an operation
- Receiver: Knows how to perform the operations for the request
- Invoker: Asks the command to carry out the request
- Client: Creates the concrete command and sets its receiver
For more information on these terms and the pattern in general you should take a look at the book.
The following class diagram outlines the high level view of the pattern and the classes comprising the pattern.
Here is a very simple implementation in Go. I have chosen Go because the language doesn’t support all the constructs other statically typed languages do. In this case I am referring to Inheritance and Interfaces. This difference in Go makes for an interesting implementation. As you will see the majority of these patterns are usually shown in C++, Java or C#.
As you know Go does not support inheritance and unlike other statically typed languages, in Go a Type does not explicitly implement an interface like for example Java, C++, C# or Swift. Instead it’s a little (and I mean syntactically) like Python’s Duck Typing, where as long as a Type contains a method with the same signature as one defined in the interface, you can invoke such method from the interface. As such:
|
|
For a greater understanding of Interfaces in Go you should take a look at this really great blog post.
The Command pattern
The following is a simple implementation of the pattern without the ‘Receiver’ part of the pattern. Please note that the main function acts as the ‘Client’.
The interface
|
|
The concrete command
|
|
The Invoker and Client
|
|
The example above is very simplistic and if you have read ‘Design Patterns’ you will immediately note that I am creating an instance of the ConcreteCommand directly within the Invoker, and this is not the way it should be done.
So let’s take a look at the revised Invoker and Client code. Ideally the Client is the one that creates the instances of the ConcreteCommand and Receiver, which it then passes onto the Invoker which is in turn responsible for actually invoking the correct command (based on the business logic of the app).
|
|
Of course the Receiver is still missing from the code, but it should be now clear how the pattern works and it’s quite simple to add a specialized Receiver should you choose to.
