How to use the command design template in C #

0

Design patterns are proven solutions used to solve common design problems and reduce code complexities. Gang of Four design patterns fall into three categories:

  • Creative – models related to the creation of objects
  • Structural – models related to the assembly of objects
  • Behavioral – models related to the collaboration of objects and the separation of responsibilities

The command design model belongs to the category of behavior models. This article explores how we can work with the command design model in C #.

What is the order design pattern?

The intention of the control design model is to decouple the requester of an action from the object that performs the action. In the order design model, a request is encapsulated as an object that contains all of the information about the request. This object is then passed to a summoner object. The summoner object then searches for the appropriate object to handle the command and passes the command to the object.

The order design template is a good choice when you want to implement callbacks, queuing tasks, tracking history, and undo / redo functionality in your application. The command model is a good choice for implementing retry mechanisms – when your application wants to retry connecting to a service at a later time that is not operational at the moment. The command model is also used in message queuing applications, that is, applications that need to recover from data loss.

Participants in the control design model

In a typical implementation of the Command model, you have four components: the command, the summoner, the receiver, and the client. The participants in the control design model are:

  • Command – provides an interface to perform an operation
  • ConcreteCommand – extends the Command interface and implements the Execute method
  • Client – instantiate a ConcreteCommand class
  • Invoker – informs the command to execute the request
  • Receiver – contains the logic for executing the operations associated with the request

Example of a command design template in C #

In the next section, we’ll explore how to implement the command design pattern. In our example, we’ll implement a simple calculator using the following classes:

  • Command (command abstract base class)
  • SimpleCalculator (receiver class)
  • AddCommand (concrete command class)
  • SubstractCommand (concrete command class)
  • Multiply Command (concrete command class)
  • DivideCommand (concrete command class)
  • Invoker (Invoker class)

Create the Command abstract base class in C #

Consider the following abstract base class named Command which contains the declaration of the Execute method.

public abstract class Command
    {
        protected SimpleCalculator receiver;
        public Command(SimpleCalculator receiver)
        {
            this.receiver = receiver;
        }
        public abstract int Execute();
    }

The following enumeration shows the operations that will be supported in our simple calculator.

public enum CommandOption
    {
        Add, Substract, Multiply, Divide
    }

Create the Receiver class in C #

The following is a class named SimpleCalculator. This class acts as a sink and contains the definition of the Add, Subtract, Multiply, and Divide methods.

public class SimpleCalculator
    {
        private int _x, _y;
        public SimpleCalculator(int a, int b)
        {
            _x = a;
            _y = b;
        }
        public int Add()
        {
            return _x + _y;
        }
        public int Subtract()
        {
            return _x - _y;
        }
        public int Multiply()
        {
            return _x * _y;
        }
        public int Divide()
        {
            return _x / _y;
        }
    }

Create concrete command classes in C #

Concrete Command classes extend the Command abstract base class and implement the Execute method as shown below.

    public class AddCommand : Command
    {
        private SimpleCalculator _calculator;
        public AddCommand(SimpleCalculator calculator) : base(calculator)
        {
            _calculator = calculator;
        }
        public override int Execute()
        {
            return _calculator.Add();
        }
    }
    public class SubtractCommand : Command
    {
        private SimpleCalculator _calculator;
        public SubtractCommand(SimpleCalculator calculator) :
        base(calculator)
        {
            _calculator = calculator;
        }
        public override int Execute()
        {
            return _calculator.Subtract();
        }
    }
    public class MultiplyCommand : Command
    {
        private SimpleCalculator _calculator;
        public MultiplyCommand(SimpleCalculator calculator) :
        base(calculator)
        {
            _calculator = calculator;
        }
        public override int Execute()
        {
            return _calculator.Multiply();
        }
    }
    public class DivideCommand : Command
    {
        private SimpleCalculator _calculator;
        public DivideCommand(SimpleCalculator calculator) :
        base(calculator)
        {
            _calculator = calculator;
        }
        public override int Execute()
        {
            return _calculator.Divide();
        }
    }

Create the Invoker class in C #

The following code snippet demonstrates the Invoker class. It contains two methods, SetCommand and Execute. While SetCommand is used to assign the command object to the private command reference in the Invoker class, Execute is used to execute the command.

    public class Invoker
    {
        private Command _command;
        public void SetCommand(Command command)
        {
            _command = command;
        }
        public int Execute()
        {
            return _command.Execute();
        }
    }

The command design model in action in C #

Finally, the following code snippet demonstrates how you can perform a simple calculation using the SimpleCalculator class.

static void Main(string[] args)
        {
            SimpleCalculator calculator = new SimpleCalculator(15, 3);
            var addCommand = new AddCommand(calculator);
            var substractCommand = new SubtractCommand(calculator);
            var multiplyCommand = new MultiplyCommand(calculator);
            var divideCommand = new DivideCommand(calculator);
            Invoker invoker = new Invoker();
            invoker.SetCommand(addCommand);
            Console.WriteLine("Result is {0}", invoker.Execute());
            invoker.SetCommand(substractCommand);
            Console.WriteLine("Result is {0}", invoker.Execute());
            invoker.SetCommand(multiplyCommand);
            Console.WriteLine("Result is {0}", invoker.Execute());
            invoker.SetCommand(divideCommand);
            Console.WriteLine("Result is {0}", invoker.Execute());
            Console.ReadLine();
        }

The command design model supports scalability and reduces the coupling that exists between the invoker and receiver of a command. Because the request is wrapped in a stand-alone object, you can parameterize methods with different requests, save requests to a queue, and even support operations that can be redone or rolled back.

Do more with C #:

Copyright © 2019 IDG Communications, Inc.


Source link

Share.

Leave A Reply