Skip to main content

Command Palette

Search for a command to run...

The Command Design Pattern

Updated
โ€ข3 min read
The Command Design Pattern
P

Hello, I'm Paras Kaushik! ๐Ÿ‘‹ I'm a dedicated software engineer based in India, specializing in C++ and proficient in the MERN stack.

๐Ÿค Interested in collaborating on innovative projects that require my technical expertise.

๐Ÿ’ฌ Passionate about participating in discussions related to software architecture and best practices.

๐Ÿ“ง Feel free to reach out to me via email: [paraskaushik12@gmail.com]

๐Ÿ”— Connect with me on LinkedIn: [https://www.linkedin.com/in/the-paras-kaushik/]

Understanding the Problem

  • Ordinary code statements are perishable, for example

    • you cannot undo a field/property assignment

    • you cannot directly take a sequence of actions that you just made and you cannot serialise them (to a db for example)

    • there is no "record" for this series of operations

  • The command object enables us to create an object that represents an operation

  • This pattern has use cases in GUI commands, multi-level undo/redo, macro recording and more for example in Excel a MACRO is a sequence of commands that gets recorded one after another and they can be played back again and again and we can also undo them one by one or all at once ,this is also a representation of command design pattern

  • The command design pattern is an object which represents an instruction to perform a particular action. It contains all the info necessary for the action to be taken

  • Suppose we want to manipulate the above bank account such that we have a proper record that the bank account was manipulated

  • We can directly call the deposit and withdraw functions from the above class instance but they would be perishable and we would not be able to maintain a log for them

  • So we are going to create an extra object -Command- for performing all operations

  • Above we have a list of commands - a record of our operations, we have our audit log now on how the account was manipulated, we can even add functionality for rollback now (undo our commands now)

  • but undo functionality must be implemented carefully, if somebody wants to withdraw the money and the operation fails, undoing such an operation should also do nothing

  • If we assume that the undo and redo operations are symmetric - which they are not ,undo operations of the command can be implemented like :

  • so currently in the above code, if somebody who doesn't have a million withdraws a million, the operation will fail but if we undo that operation - a million dollars would be deposited - this is because undo and redo in this case are not symmetric- this can be solved by simply maintaining a success flag with every command

  • So the command abstraction will now look like

  • So there we have it we have done undo/redo operations and also maintained a log of all the bank account modifications we do using the command design pattern

NOTE

  • Command Query Separation(CQS): Command causes mutation whereas a query does not cause mutation but returns a value

More from this blog

Blogs by Paras

52 posts

Hello, I'm Paras Kaushik! ๐Ÿ‘‹ I'm a dedicated software engineer based in India, specializing in C++ and proficient in the MERN stack. ๐Ÿ’ผ Open to Collaboration