Work In Progress - I am still updating the content and samples parellel.
Problem Statement:
1. Need to issue requests to objects without knowing anything about the operation being requested or the receiver of the request (who receives the request and perform the necessary action).
2. Want to implement Redo/Undo, Previous/Next, Push/Pop and Copy/Paste operations based on the user request.
3. Want an object-oriented callback.
4. Want to allow the parameterization of clients with different requests.
5. Want to allow saving the requests in a queue.
6. Want to implement Sell/Buy Stocks or trades functionality.
Solution:
Instead of sending the request and required parameters directly to the receiver (who receives the request and perform the necessary action), store the request and required parameters in another object (command object) and
let that object (command object) or the other object (Invoker) decide when and what time to pass to receiver.
So that the command may be executed immediately or use it later.
OR
Decouple the client from the request(s) as well as the object that will be handling the request.
OR
Encapsulate a request in an object.
By encapsulating the request we gain the following support if needed:
• Redo and Undo operations.
• Requests can be stored in queue and executed when needed.
• Requests can be logged.
• Composition of transactions inside an object that include the transaction atomic operations.
Command Pattern:
Decouple the ‘object that invokes the operation’ from the ‘object that knows how to perform it’. This implementation also called as Producer - Consumer design pattern.
• The command pattern is used to express a request, including the call to be made and all of its required parameters, in a command object
• The command object does not contain the functionality that is to be executed.
• It contains only the information required to perform an action.
• The main functionality is contained within receiver objects.
• This removes the direct link between the command definitions and the functionality, promoting loose coupling.
• Use another object called Invoker, for controlling and determining the time of execution of the command.
When to use Command Pattern?
The command pattern is more useful when application requires series of requests (store them in command object) to the same object.
The command objects can be held in a queue and processed sequentially. If each command is stored on a stack after it is executed, and if the commands are reversible, this allows the implementation of a rollback or multi-level
undo facility.
Command Pattern Principle:
• The command object does not contain the main logic/functionality that is to be executed.
• Command object contains only the information required to perform an action.
• The main logic/functionality is contained within receiver objects.
• Interface separation (the invoker is isolated from the receiver).
• Time separation (stores a ready-to-go processing request that’s to be stated later).
Note:
1. Should not use command just as a link between the receiver and the actions that carry out the request.
2. Do not implement everything in the command itself, without sending anything to the receiver.
Command Pattern Terms:
Command (Command – Request or Collection of Requests)
• Declares an interface/ abstract class for executing the operation(s)
• It defines a protected field that holds the Receiver that is linked to the command, which is usually set via a constructor.
• The class also defines an abstract method that is used by the Invoker to execute commands.
ConcreteCommand (Optional)
• Defines a binding/link between a Receiver object and receiver’s action
• Extends the Command interface, Implements Execute method by invoking the corresponding operation(s) on Receiver
• Concrete command classes are subclasses of Command. In addition to implementing the Execute method, they contain all of the information that is required to correctly perform the action using the linked Receiver object.
Client (Application)
• Creates a Command or ConcreteCommand object and sets/links the receiver.
• Also provides all the necessary information required to call the method at a later time.
Invoker (Controls the request - Optional)
• It initiates the execution of commands and asks the command to carry out the request.
• Decides when the method should be called.
• The invoker could be controlled by the Client object. However, the invoker may be disconnected from the client. For example, the client could create a queue of commands that are executed periodically by a timed event.
Receiver (Target of the request)
• The main logic will be implemented here and it knows how to perform the necessary actions.
• It contains the methods that are executed when one or more commands are invoked.
• This allows the actual functionality to be held separately to the Command definitions.
How Command Patter Works?
1. When the application (client) has to perform a command, it creates the command and sent it to the invoker.
2. The Invoker takes the command and places it in a queue, and it calls the execute method of the command and adds it to a list containing all the commands.
3. The execute method of the command delegate the call to the receiver object.
4. When undo operations are performed the invoker uses the list with all executed commands and calls for each one the unexecuted method. The redo operation works in the same manner.
5. The ConcreteCommand (optional) that is in charge of the requested command sending its result to the Receiver.
Command Pattern Implementation Example:
For E.g In a restaurant scenario, the waiter (Invoker) takes the order from the customer on his pad.
The order is then queued for the order cook and gets to the cook (Receiver) where it is processed.
Refer the code comments below and follow the steps.
C#
Edit|Remove
csharp
using System;
using System.Collections.Generic;
using System.Windows.Input;
namespace CommandPatternDemo
{
// Receiver - The main logic will be implemented here and it knows how to perform the necessary actions.
// In Restaurant scenario e.g. - The Cook
class Receiver
{
public void Action()
{
Console.WriteLine("The Main operations performed here. Receiver.Action()");
}
}
// Command - Declares an interface/ abstract class for executing the operation(s).
// In Restaurant scenario e.g. - A single order or multiple orders stored in collection
abstract class Command
{
//A protected field that holds the Receiver that is linked to the command, which is usually set via a constructor.
protected Receiver receiver;
public Command(Receiver receiver)
{
this.receiver = receiver;
}
public abstract void Execute();
}
// ConcreteCommand - Defines a binding/link between a Receiver object and Receiver's action
// Extends the Command interface, Implements Execute method by invoking the corresponding operation(s) on Receiver
// In Restaurant scenario e.g. - Pizza Order, Burger Order etc
class ConcreteCommand : Command
{
// Constructor takes the linked Receiver object, the same receiver object (called linked receiver) might be used by other concrete commands which will be passed from client.
public ConcreteCommand(Receiver receiver) : base(receiver)
{
}
public override void Execute()
{
receiver.Action();
}
}
// Invoker - Asks the command to carry out the request.
// Decides when the method should be called.
// In Restaurant scenario e.g. - The Waiter
class Invoker
{
private Command _commandObject;
public void SetCommand(Command commandObject)
{
this._commandObject = commandObject;
}
public void ExecuteCommand()
{
_commandObject.Execute();
}
}
// Client - Creates a ConcreteCommand object and sets its receiver.
// Instantiates the command object and provides the information required to call the method at a later time.
// In Restaurant scenario e.g. - The Customer
class Client
{
static void Main()
{
// Create receiver, command, and invoker
Receiver ReceiverObject = new Receiver();
//Creates a ConcreteCommand object and sets its receiver
//Instantiates the command object and provides the information required to call the method at a later time.
Command CommandObject = new ConcreteCommand(ReceiverObject);
// Invoker - Asks the command to carry out the request.
// Decides when the method should be called.
Invoker InvokerObject = new Invoker();
InvokerObject.SetCommand(CommandObject);
InvokerObject.ExecuteCommand();
// Wait for user
Console.Read();
}
}
}
using System;
using System.Collections.Generic;
using System.Windows.Input;
namespace CommandPatternDemo
{
// Receiver - The main logic will be implemented here and it knows how to perform the necessary actions.
// In Restaurant scenario e.g. - The Cook
class Receiver
{
public void Action()
{
Console.WriteLine("The Main operations performed here. Receiver.Action()");
}
}
// Command - Declares an interface/ abstract class for executing the operation(s).
// In Restaurant scenario e.g. - A single order or multiple orders stored in collection
abstract class Command
{
//A protected field that holds the Receiver that is linked to the command, which is usually set via a constructor.
protected Receiver receiver;
public Command(Receiver receiver)
{
this.receiver = receiver;
}
public abstract void Execute();
}
// ConcreteCommand - Defines a binding/link between a Receiver object and Receiver's action
// Extends the Command interface, Implements Execute method by invoking the corresponding operation(s) on Receiver
// In Restaurant scenario e.g. - Pizza Order, Burger Order etc
class ConcreteCommand : Command
{
// Constructor takes the linked Receiver object, the same receiver object (called linked receiver) might be used by other concrete commands which will be passed from client.
public ConcreteCommand(Receiver receiver) : base(receiver)
{
}
public override void Execute()
{
receiver.Action();
}
}
// Invoker - Asks the command to carry out the request.
// Decides when the method should be called.
// In Restaurant scenario e.g. - The Waiter
class Invoker
{
private Command _commandObject;
public void SetCommand(Command commandObject)
{
this._commandObject = commandObject;
}
public void ExecuteCommand()
{
_commandObject.Execute();
}
}
// Client - Creates a ConcreteCommand object and sets its receiver.
// Instantiates the command object and provides the information required to call the method at a later time.
// In Restaurant scenario e.g. - The Customer
class Client
{
static void Main()
{
// Create receiver, command, and invoker
Receiver ReceiverObject = new Receiver();
//Creates a ConcreteCommand object and sets its receiver
//Instantiates the command object and provides the information required to call the method at a later time.
Command CommandObject = new ConcreteCommand(ReceiverObject);
// Invoker - Asks the command to carry out the request.
// Decides when the method should be called.
Invoker InvokerObject = new Invoker();
InvokerObject.SetCommand(CommandObject);
InvokerObject.ExecuteCommand();
// Wait for user
Console.Read();
}
}
}
Related Patterns:
(Will be explained in detail in their respective articles later)
Composite Pattern:
For adding new commands to the application we can use the composite pattern to group existing commands in another new command called Composite commands
This way, macros can be created from existing commands.
Chain of Responsibility Pattern:
• Chain of Responsibility, Command, Mediator, and Observer, address how we can decouple senders and receivers, but with different trade-offs.
• Command normally specifies a sender-receiver connection with a subclass.
• Chain of Responsibility can use Command to represent requests as objects.
Memento Pattern:
• Command and Memento act as magic tokens to be passed around and invoked at a later time.
• In Command, the token represents a request; in Memento, it represents the internal state of an object at a particular time.
• Polymorphism is important to Command, but not to Memento because its interface is so narrow that a memento can only be passed as a value.
• Command can use Memento to maintain the state required for an undo operation.
• A Command that must be copied before being placed on a history list acts as a Prototype.
Advantages of Command Pattern:
Queue up requests for action at a later time.
Create a log of requests, for possible re-application after returning the system to a backup check point following a crash
Bundle up a series of plodding detailed requests into a larger transaction (macro) that makes the business intention clearer from the client's perspective
Flexibility where we can provide some runtime configuration to the commands which are issued
Transfer of the command to a different process for handling
Reference Links:
Different Types of Commands:
ApplicationCommands - Cut, Copy, and Paste.
EditingCommands – Toggle Bold, Italic and decrease/increase Font Size.
NavigationCommands – Previous/Next Page and Search.
MediaCommands – Play, pause, increase/decrease volume.
ComponentCommands - These commands have a lot in common with some of the other libraries like NavigationCommands and EditingCommands since they include things like MoveDown and ExtendSelectionLeft.
Command Pattern used in WPF:
WPF introduces routed commands, which combine the command pattern with event processing. As a result the command object no longer contains a reference to the target object nor a reference to the application code. Instead,
invoking the command object's execute command results in a (so called Executed Routed Event) which during the event's tunneling or bubbling may encounter a (so called binding) object which identifies the target and the application code, which is executed at
that point.
NavigationCommands
MediaCommands
ApplicationCommands
ComponentCommands
EditingCommands
RoutedCommand
RoutedUICommand
Thank you for reading my article. Drop all your questions/comments in QA tab give me your feedback with
star rating (1 Star - Very Poor, 5 Star - Very Good).