Sunday, May 28, 2017

Command Pattern

Command design pattern can be used while designing Menu Items, Tool Bar, Status Bar etc functionalities in application. This pattern can also be useful to provide Undo/Redo like functionalities in application. Command Pattern falls under behavioral pattern of GOF (Gang of Four) pattern.

When to use –


Command Pattern encapsulates request under an object and pass it to the invoker object. The invoker object will pass it to proper command object which will execute the command. This pattern commonly used in UI Buttons, Menu, Tool Bar, Status Bar, Progress Bar etc in many applications. This pattern can also be used to provide multiple level Undo/Redo functionalities for applications.  

Major components of command pattern –


Command – This is an interface which specifies execute action.
Concrete Command – This is concrete class which provides implementation for execute operation.
Client – This class creates and executes commands.
Invoker – This class will ask the command to execute their actions.
Receiver – This class knows how to perform action attached with request.

See below example of Command pattern.

Code –
//Command interface
public interface ICommand
{
    void Execute();
    string Name { get; }
}
//Concrete Command class
public class BuyCommand : ICommand
{
    private Product Product;
    public string Name
    {
        get
        {
            return "Buy Command";
        }
    }
    public BuyCommand(Product product)
    {
        Product = product;
    }
    public void Execute()
    {
        Console.WriteLine("Executing {0}", Name);
        Product.Buy();
    }
}
//Concrete Command class
public class SellCommand : ICommand
{
    private Product Product;
    public string Name
    {
        get
        {
            return "Sell Command";
        }
    }
    public SellCommand(Product product)
    {
        Product = product;
    }
    public void Execute()
    {
        Console.WriteLine("Executing {0}", Name);
        Product.Sell();
    }
}
//Receiver class
public class Product
{
    public int Quantity { get; set; }
    public string Name { get; set; }
    public Product(string prodName, int qty)
    {
        Name = prodName;
        Quantity = qty;
    }
    public void Buy()
    {
        Console.WriteLine("Purchased {0} quantities of {1}", Quantity, Name);
    }
    public void Sell()
    {
        Console.WriteLine("Sold {0} quantities of {1}", Quantity, Name);
    }
}
//Invoker class
public class Portal
{
    public string PortalName { get; set; }
    public Portal(string name)
    {
        PortalName = name;
    }
    public List<ICommand> orderList = new List<ICommand>();
    public void AddOrder(ICommand cmd)
    {
        orderList.Add(cmd);
    }
    public void ExecuteOrder()
    {
        Console.WriteLine("Executing all orders from {0}", PortalName);
        foreach(var order in orderList)
        {
            order.Execute();
        }
    }
}
//Client class
class Program
{
    static void Main(string[] args)
    {
        Product laptop = new Product("Laptop", 2);
        BuyCommand buyLaptop = new BuyCommand(laptop);
        SellCommand sellLaptop = new SellCommand(laptop);

        Portal portal = new Portal("Amazon.in");
        portal.AddOrder(buyLaptop);
        portal.AddOrder(sellLaptop);

        portal.ExecuteOrder();

        Console.ReadLine();
    }
}

Output –




As you can see in this example, user can create receiver object and also create objects for multiple commands. In this example Product is Receiver class and Portal is invoker class. The portal object will invoke BuyCommand and SellCommand as per their order. This example can also be extended to add Undo/Redo functionality via using Stack and modifying invoker class.

You can download full code from Gist.

I hope this article helps you to know more about Command Design Pattern. Please leave your feedback in comments section below.

References –

See Also –

No comments:

Post a Comment