12 - Command
Tags: flutter, dart, oop, programming
Published: 2021-04-05 16:42:35

Previously in the series, I have analysed and implemented one of the most popular and useful creational design patterns — Abstract Factory. This time, I would like to introduce an OOP design pattern that belongs to the category of behavioural design patterns — the Command.

## Table of Contents

* What is the Command design pattern?
* Analysis
* Implementation
* Your Contribution

## What is the Command design pattern?

![A Dangerous Command](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e8sra93h7vt8pd0tdc0f.gif)

**Command**, also known as **Action** or **Transaction**, is one of the **behavioural** design patterns which intention is described in the [GoF book](https://en.wikipedia.org/wiki/Design_Patterns):

> Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable opera­tions.

That is, by encapsulating the request as an object, the client is completely decoupled from any of the details of how that command is implemented or how it will get executed — the client doesn’t have to care about any dependencies.

There are multiple components of which the Command design pattern is consisted of. Usually, **Command** objects serve as links between various UI and business logic objects. In this case, the command object could be bound to the UI element at runtime by the **Client** and that particular UI component, called **Sender**, invokes the request. The **Sender** triggers the assigned **Command** instead of sending the request directly to the **Receiver** - a simple or complex object which contains the actual logic for the request to be fulfilled. A specific **Command** passes the call to the receiver which does the actual work. As a result, commands become a convenient middle layer that reduces coupling between the UI and business logic layers.

Let’s move to the analysis and implementation parts to understand the details about this pattern and learn how to implement it!

## Analysis

The general structure of the Command design pattern looks like this:

![Command Class Diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/53kjfvmy90vwoohgnzpb.png)

* *Command* — declares an interface for executing an operation;
* *Concrete Commands (Command1/Command2)* — implement various kinds of requests by invoking the corresponding operation(s) on *Receiver*;
* *Invoker* — the sender class which triggers the *Command* instead of sending the request directly to the *Receiver*;
* *Receiver* — knows how to perform the operations associated with carrying out a request. Any class may serve as a *Receiver*;
* *Client* — creates a *Concrete Command* object and sets its *Receiver*.

### Applicability

The Command design pattern could be used when you want to parameterize objects by an action to perform. That is, the operation (command) is extracted to a separate class which object could be passed as a method argument, stored inside another object or the linked command could be switched at runtime.

Furthermore, the Command design pattern is useful when you want to queue operations, schedule their execution, or execute them remotely. Since the command itself is just a simple class, its object (as any other object) could be serialized, stored, e.g. in the database or a text file and later restored as the initial command and executed. This is useful when you want to schedule a specific task that should be executed at a particular time, or on a recurring schedule.

Also, one of the most popular use-case for the Command is to use it for creating reversible operations. To be able to revert operations, you need to implement the history of performed operations. The command history is a stack that contains all executed command objects along with related backups of the application’s state.

Finally, the Command design pattern helps you write cleaner and reusable code. By using this pattern, you propagate the **Single Responsibility Principle** (the operation logic is decoupled from the component which performs that particular operation) and the **Open/Closed Principle** (introducing new commands to the application does not require changing the existing code).

## Implementation

![Let's Have Some Fun](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9p6t06vm9etdrwpkb6e6.gif)

To show the Command design pattern in action, we will implement a fake graphics editor. The editor itself is *super-ultra-mega-duper* simplified (well, *Photoshop* should have started from something, right?) and provides the following functionality:

* There is only one shape visible on the screen which cannot be removed, but its parameters (colour, height and width) could be adjusted using buttons;
* Change the shape’s colour to a random one;
* Change the shape’s height to a random value between 50 and 150;
* Change the shape’s width to a random value between 50 and 150;
* All of the operations could be undone using the Undo button.

And that is basically it. I know, as a graphics editor, this one sounds terrible, but it would be more than enough to demonstrate the purpose of the Command design pattern.

The main idea behind the implementation of the mentioned graphics editor is to separate the actual business logic of the button from its representation. To achieve this, each operation (request) of the button is encapsulated in a separate class object. Also, by using the Command design pattern, the implementation of *undo* operation is possible — since every command is encapsulated in a separate class, it is easy to store an objects’ list of already executed commands as well as undoing the last operation by taking the last command from the list and calling the *undo()* method on it.

Let’s check the class diagram first and then investigate each class/component to see how the Command design pattern could help us building such a graphics editor.

### Class diagram

The class diagram below shows the implementation of the Command design pattern:

![Command Implementation Class Diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/584wkd9gvv7etfwxxaz0.png)

*Command* is an abstract class that is used as an interface for all the specific commands:

* *execute()* — an abstract method that executes the command;
* *getTitle()* — an abstract method that returns the command’s title. Used in command history UI;
* *undo()* — an abstract method that undoes the command and returns the receiver to the previous state.

*ChangeColorCommand*, *ChangeHeightCommand* and *ChangeWidthCommand* are concrete command classes that implement the abstract class *Command* and its methods.

*Shape* is a receiver class that stores multiple properties defining the shape presented in UI: *color*, *height* and *width*.

*CommandHistory* is a simple class that stores a list of already executed commands (*commandList*) and provides methods to add a new command to the command history list (*add()*) and undo the last command from that list (*undo()*).

*CommandExample* initializes and contains *CommandHistory*, *Shape* objects. Also, this component contains multiple *PlatformButton* widgets which have a specific implementation of *Command* assigned to each of them. When the button is pressed, the command is executed and added to the command history list stored in *CommandHistory* object.

### Shape

A simple class to store information about the shape: its color, height and width. Also, this class contains a named constructor to create a shape object with pre-defined initial values.

![shape.dart](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fcfvjnp46xe5s8mx1oqs.png)

### Command

An interface that defines methods to be implemented by the specific command classes. Dart language does not support the interface as a class type, so we define an interface by creating an abstract class and providing a method header (name, return type, parameters) without the default implementation.

![command.dart](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xaajo4ifl2s6egrvp3ti.png)

### Commands

*ChangeColorCommand* — a specific implementation of the command which changes the color of the *Shape* object.

![change_color_command.dart](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m62xkiw5m55zw9takffq.png)

*ChangeHeightCommand* — a specific implementation of the command which changes the height of the *Shape* object.

![change_height_command.dart](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p276vnuzvyfvbqra5nex.png)

*ChangeWidthCommand* — a specific implementation of the command which changes the width of the *Shape* object.

![change_width_command.dart](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yhfdduy06t0rt5vll24w.png)

### CommandHistory

A simple class that stores a list of already executed commands. Also, this class provides *isEmpty* and *commandHistoryList* getter methods to return true if the command history list is empty and return a list of command names stored in the command history respectively. A new command could be added to the command history list via the *add()* method and the last command could be undone using the *undo()* method (if the command history list is not empty).

![command_history.dart](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5gx7i1t6q75eb41esnxv.png)

### Example

First of all, a markdown file is prepared and provided as a pattern’s description:

![Command Markdown](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ztkyawt8soejrbn2hr3d.gif)

*CommandExample* contains *CommandHistory* and *Shape* objects. Also, this widget contains several *PlatformButton* components, each of which uses a specific function executing a concrete command. After the command’s execution, it is added to the command history list stored in the *CommandHistory* object. If the command history is not empty, the *Undo* button is enabled and the last command could be undone.

![command_example.dart](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s01tg1sqp1rt5eqgnreh.png)

The client code (UI elements, command history, etc.) isn’t coupled to concrete command classes because it works with commands via the command interface. This approach allows introducing new commands into the application without breaking any existing code.

![Command Example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3a2tg38uxbz81y8n8c09.gif)

As you can see in the example, by triggering a specific command, its object is created, executed and added to the command history list. Hence, it is possible to undo the command even though it was executed several steps before — that’s one of the advantages of using the Command design pattern.

All of the code changes for the Command design pattern and its example implementation could be found [here](https://github.com/mkobuolys/flutter-design-patterns/pull/13).

## Your Contribution

💖 or 🦄 this article to show your support and motivate me to write better!
💬 Leave a response to this article by providing your insights, comments or wishes for the next topic.
📢 Share this article with your friends, colleagues on social media.
➕ Follow me on dev.to or any other social media platform.
⭐ Star the [Github](https://github.com/mkobuolys/flutter-design-patterns) repository.