C# Command Design Pattern

C# Command Design Pattern Tutorial

Link to Source Code

Command pattern allows you to store list of code that is executed many times or at a later time. It also gives you easy way to implement Undo() that can just have opposite effect or undo multiple command, if commands are stored in list. This pattern is supports encapsulation, which is always a good thing. It may look complicated, it involves multiple classes:

Receiver – that performs the Action associated with the request.

Invoker  –that asks the command to carry out the request

Command -this is an interface which specifies the Execute and/or Undo operation.

Client – creates instance of an invoker, command and receiver and connects them.

As usual I’ll be using example related to video games. In my example I created simulation where Enemy can enter the field on the battlefield that can Heal him or it can add a Buff. I have two types of enemies Goblin and dragon, just to demonstrate the example of multiple receivers. When enemy exits the field the opposite action is triggered.

 

UML Diagram

l7

Receiver

Lets start by creating interface for Enemies. Every enemy that implements this interface can either take damage, heal, and Turn Buff OFF and ON.


interface IEnemy
{
  string Damage();
  string Heal();
  string BuffON();
  string BuffOFF();
}

Each method will return a string with massage about current status.

Here is implementation of the interface in one of the Enemy Class. Second One is very similar and you can find it in source code.


class Goblin : IEnemy
{
  public string BuffOFF()
  {
    return "Goblin enters the field-Buff is ON";
  }

  public string BuffON()
  {
    return "Goblin exits the field-Buff is OFF";
  }

  public string Damage()
  {
    return "Goblin exits the field- takes damage";
  }

  public string Heal()
  {
     return "Goblin enters the field- heals";
  }

Command

This interface will specify how retriever will respond to execute()and undo() commands.

interface ICommand
{
  void Execute();
  void UnDo();
} 

implementation of this interface requires a instance of an IEnemy receiver, in class constructor we pass the receiver that will be manipulated by the command. Again I’m showing here just one of two Classes, because both are identical.


class Heal : ICommand
{
  IEnemy _receiver;
  // Constructor
  public Heal(IEnemy receiver)
  {
    _receiver = receiver;
  }

  public void Execute()
  {
    Console.WriteLine(_receiver.Heal());
  }
  public void UnDo()
  {
    Console.WriteLine(_receiver.Damage());
  }
}

 

Invoker

In my example i’m simulating situation when enemy enters the field on the map, that triggers the commands. In the invoker we pass instance of command that we want to execute.


class Field
{
  private ICommand _command;

  public void SetCommand(ICommand command)
  {
    this._command = command;
  }

  public void EnterField()
  {
  _command.Execute();
  }
  public void ExitField()
  {
  _command.UnDo();
  }
}

Client

This is the last part of the program that connect everything together. In this specific example I chose the situation when Enemy Goblin Enters the Field, what trigger the Heal command. After leaving the field Goblin Takes Damage.


static void Main()
{
  // Create receiver, command, and invoker
  IEnemy receiver = new Goblin();
  ICommand command = new Heal(receiver);
  Field invoker = new Field();

  // Set and execute command
  invoker.SetCommand(command);
  invoker.EnterField();
  invoker.ExitField();

  Console.ReadKey();
}

This was just a simple demonstration of the pattern, one way of extending the functionality of it is to store command in the generic list, this way we can undo multiple commands or execute command already executed in the past. I hope you like will find it useful. In my next article I’ll cover on of the last design patters. Stay Awesome!

Author: indiedevart

Indie Games Developer

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s