The Command pattern is a behavioral design pattern that we can use to turn a request into an object which contains all the information about the request.

The Command design pattern is quite popular in C#, especially when we want to delay or queue a request’s execution or when we want to keep track of our operations. Furthermore, this possibility to keep track of our operations gives us the opportunity to undo them as well.

The source code is available at the Command Design Pattern – Source Code.

For the main page of this series check out C# Design Patterns.

This article is divided into the following sections:

Implementation of Command Design Pattern

The Command design pattern consists of the Invoker class, Command class/interface, Concrete command classes and the Receiver class.  Having that in mind, in our example, we are going to follow the same design structure.

So, what we are going to do is write a simple app in which we are going to modify the price of the product that will implement the Command design pattern.

That being said, let’s start with the Product receiver class, which should contain the base business logic in our app:

So this is our receiver class, which has a pretty straightforward logic. We just increase or conditionally decrease the product’s price. Finally, we have the ToString method, to be able to print our object.

Now the Client class can instantiate the Product class and execute the required actions. But the Command design pattern states that we shouldn’t use receiver classes directly. Instead, we should extract all the request details into a special class – Command.

And that is exactly what we are going to do.

The first thing we are going to do is to add the ICommand interface:

Just to enumerate our price modification actions, we are going to add a simple PriceAction enumeration:

Finally, let’s add the ProductCommand class:

As we can see, the ProductCommand class has all the information about the request and based on that executes required action.

To continue on, let’s add the ModifyPrice class, which will act as Invoker:

This class can work with any command that implements the ICommand interface and store all the operations as well.

Now, we can start working with the client part:

This should be our result:

Command design pattern - working solution

Excellent. We can see the order of our actions and the correct price after modifications.

Having in mind that we are keeping track of our actions in the Invoker class, we can use that to Undo our operations if we want to.

So, let’s try that.

Implementing Undo Operation in the Command Design Pattern

To implement the Undo operation let’s start with the ICommand interface modification:

Then, let’s modify the ProductCommand class by adding the UndoAction method:

Of course, we have to modify the ModifyPrice class as well by adding the UndoActions method:

Please note that we are not using the Linq Reverse method but the Enumerable.Reverse() instead. That’s because the Linq method would mutate our list and we don’t want that. All we want is just reversed list but without mutating the original list itself.

Now, when the Client class calls the UndoActions method, it will iterate through all the operations from the list and execute the opposite operation from the previously required.

Let’s try that:

The result:

Undo action - Command pattern

Everything works as it supposed to.

Improving the Solution

We have implemented the Command design pattern into our app, and there is nothing wrong with that. But there is one flaw in our solution which is not related to the Command pattern but to the business logic overall.

If we were to change the decreased amount from 25 to 2500 for example, what would happen? Well, we have the protection for that in the DecreasePrice method and it will not affect the result, and you are right. But it is going to affect the Undo actions.

Let’s see how:

This is going to be the result:

Undo wrong result - command pattern

As you can see, our price hasn’t been decreased but the operation has been preserved in our store which caused the Undo action to fail.

So, let’s fix that.

The first thing we are going to do is to modify the DecreasePrice method in the Product class:

Now, we can modify the ProductCommand class as well:

And that is it. Now if we start our app with a decreased amount of 2500 the result would be correct:

finall solution - command pattern

Great job.

Conclusion

Even though the Command design pattern introduces complexity to our code, it can be very useful.

With it, we can decouple classes that invoke operations from classes that perform these operations. Additionally, if we want to introduce new commands, we don’t have to modify existing classes. Instead, we can just add those new command classes in our project.

If you have enjoyed reading this article and if you would like to receive the notifications about the freshly published .NET Core content we encourage you to subscribe to our blog.