Search

Command - design pattern example

The command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters.
using System;
using System.Collections;
using System.Linq;

namespace CommandPattern_demo
{
    #region ICommand Interface
    interface ICommand
    {
        string Name { get; set; }
        string Description { get; set; }
        void Run();
    }
    #endregion

    #region Command Invoker
    class CInvoker
    {
        /// 
        /// Array to hold list of commands
        /// 
        private ArrayList listOfCommands = new ArrayList();

        public CInvoker()
        {
            LoadCommands();
        }

        private void LoadCommands()
        {
            listOfCommands.Add(new cmdOpen());
            listOfCommands.Add(new cmdClose());
            listOfCommands.Add(new cmdCreate());
            listOfCommands.Add(new cmdUpdate());
            listOfCommands.Add(new cmdRetrieve());
        }

        public ICommand FindCommand(string name)
        {
            return listOfCommands.Cast<icommand>().FirstOrDefault(cmdObject => cmdObject.Name == name);
        }

        public ICommand GetCommand(string name)
        {
            foreach (var item in listOfCommands)
            {
                ICommand objCmd = (ICommand)item;
                if (objCmd.Name == name)
                {
                    return objCmd; //return the command found
                }
            }
            return null; //return if no commands are found
        }
    }
    #endregion

    #region Commands

    class cmdOpen : ICommand //command 1
    {
        private string _name = "open", _description = "opens a file";
        public string Name { get { return _name; } set { _name = value; } }

        public string Description { get { return _description; } set { _description = value; } }

        public void Run() { Console.WriteLine("running open command"); }
    }

    class cmdClose : ICommand //command 2
    {
        private string _name = "close", _description = "opens a file";
        public string Name { get { return _name; } set { _name = value; } }
        public string Description { get { return _description; } set { _description = value; } }
        public void Run() { Console.WriteLine("running close command"); }
    }

    class cmdCreate : ICommand //command 3
    {
        private string _name = "create", _description = "opens a file";
        public string Name { get { return _name; } set { _name = value; } }
        public string Description { get { return _description; } set { _description = value; } }
        public void Run() { Console.WriteLine("running create command"); }
    }

    class cmdUpdate : ICommand //Command 4
    {
        private string _name = "update", _description = "opens a file";
        public string Name { get { return _name; } set { _name = value; } }
        public string Description { get { return _description; } set { _description = value; } }
        public void Run() { Console.WriteLine("running update command"); }
    }

    class cmdRetrieve : ICommand //command 5
    {
        private string _name = "reterive", _description = "opens a file";
        public string Name { get { return _name; } set { _name = value; } }
        public string Description { get { return _description; } set { _description = value; } }
        public void Run() { Console.WriteLine("running Retrieve command"); }
    }
    #endregion

    #region MAIN
    class Program
    {
        static void Main(string[] args)
        {
            //Command pattern example
            CInvoker cmdInvoker = new CInvoker();
            ICommand cmd1 = cmdInvoker.GetCommand("open");
            cmd1.Run();
            cmdInvoker.GetCommand("close").Run();
        }
    }
    #endregion
}

Four terms always associated with the command pattern are command, receiver, invoker and client. A command object has a receiver object and invokes a method of the receiver in a way that is specific to that receiver's class. The receiver then does the work. A command object is separately passed to an invoker object, which invokes the command, and optionally does bookkeeping about the command execution. Any command object can be passed to the same invoker object. Both an invoker object and several command objects are held by a client object. The client contains the decision making about which commands to execute at which points. To execute a command, it passes the command object to the invoker object.

See example code below. Using command objects makes it easier to construct general components that need to delegate, sequence or execute method calls at a time of their choosing without the need to know the class of the method or the method parameters. Using an invoker object allows bookkeeping about command executions to be conveniently performed, as well as implementing different modes for commands, which are managed by the invoker object, without the need for the client to be aware of the existence of bookkeeping or modes.

using System;
using System.Collections.Generic;
 
namespace CommandPattern
{
    public interface ICommand
    {
        void Execute();
    }
 
    /* The Invoker class */
    public class Switch
    {
        private List<icommand> _commands = new List<icommand>();
 
        public void StoreAndExecute(ICommand command)
        {
            _commands.Add(command);
            command.Execute();
        }
    }
 
    /* The Receiver class */
    public class Light
    {
        public void TurnOn()
        {
            Console.WriteLine("The light is on");
        }
 
        public void TurnOff()
        {
            Console.WriteLine("The light is off");
        }
    }
 
    /* The Command for turning on the light - ConcreteCommand #1 */
    public class FlipUpCommand : ICommand
    {
        private Light _light;
 
        public FlipUpCommand(Light light)
        {
            _light = light;
        }
 
        public void Execute()
        {
            _light.TurnOn();
        }
    }
 
    /* The Command for turning off the light - ConcreteCommand #2 */
    public class FlipDownCommand : ICommand
    {
        private Light _light;
 
        public FlipDownCommand(Light light)
        {
            _light = light;
        }
 
        public void Execute()
        {
            _light.TurnOff();
        }
    }
 
    /* The test class or client */
    internal class Program
    {
        public static void Main(string[] args)
        {
            Light lamp = new Light();
            ICommand switchUp = new FlipUpCommand(lamp);
            ICommand switchDown = new FlipDownCommand(lamp);
 
            Switch s = new Switch();
            string arg = args.Length > 0 ? args[0].ToUpper() : null;
            if (arg == "ON")
            {
                s.StoreAndExecute(switchUp);
            }
            else if (arg == "OFF")
            {
                s.StoreAndExecute(switchDown);
            }
            else
            {
                Console.WriteLine("Argument \"ON\" or \"OFF\" is required.");
            }
        }
    }
}