Command Pattern Code Review
Code Download
- Download Description:command pattern download
- .NET Framework:3.5
- .NET Language:C#
- Date Published:2009-07-01
- Download Size:9 KB
Define the Pattern Interface and Command Objects
Define the ICommand interface to be used as the "blueprint" for the main application classes.
interface ICommand
{
Receiver Receiver { get; set; }
void Execute();
void Redo();
void Undo();
}
This interface defines the Execute, Redo and Undo methods and has a local instance of type Receiver.
The Receiver class (object) represents the class that will have the code logic to actually execute the required command,
and this is where all the work will be done.
The Paste class (object) represents a unique command that needs to be actioned.
class Paste : ICommand
{
public Receiver Receiver { get; set; }
public void Execute()
{
this.Receiver.Paste();
}
public void Redo()
{
this.Receiver.Paste();
}
public void Undo()
{
this.Receiver.Restore();
}
}
This class inherits from the ICommand object, and therefore implements the Execute, Redo and Undo methods and has a local
variable of type Receiver defined.
The Print class (object) represents another unique command that needs to be actioned.
class Print : ICommand
{
public Receiver Receiver { get; set; }
public void Execute()
{
this.Receiver.Print();
}
public void Redo()
{
this.Receiver.Print();
}
public void Undo()
{
Console.WriteLine("Cannot undo a Print!\n");
}
}
And as before, this class inherits from the ICommand object, and therefore implements the Execute, Redo and Undo methods and
has a local variable of type Receiver defined.
The difference here, between the Paste command and the Print command, is that the Print command does not have a logical
Undo process. So nothing needs doing when this method is called.
Define the Invoker and Receiver Objects
The Invoker class (object) is called by the client and is used to action the required commands.
class Invoker
{
private Receiver m_receiver;
public String ClipBoard { private get; set; }
public Int32 Count { get; private set; }
public Invoker(String name)
{
this.m_receiver = new Receiver(name);
this.Count = 0;
}
public void Execute(ICommand command)
{
if (command is Paste)
{
this.m_receiver.ClipBoard = this.ClipBoard;
}
command.Receiver = this.m_receiver;
command.Execute();
this.Count++;
}
public void Redo(ICommand command)
{
if (command is Paste)
{
this.m_receiver.ClipBoard = this.ClipBoard;
}
command.Receiver = this.m_receiver;
command.Redo();
this.Count++;
}
public void Undo(ICommand command)
{
command.Receiver = this.m_receiver;
command.Undo();
this.Count++;
}
public void Log()
{
Console.WriteLine("Logged {0} commands", this.Count);
}
}
Note the creation of the Receiver object, which will have the necessary methods defined to action the command. In this case,
there is only one Receiver object used, but could define multiple Receiver objects, if required.
The Receiver class (object) contains the logic required to action the relevant command.
class Receiver
{
private String m_name = String.Empty;
private String m_oldpage;
private StringBuilder m_page = new StringBuilder();
public String ClipBoard { get; set; }
public Receiver(String name)
{
this.m_name = name;
}
public void Paste()
{
this.m_oldpage = this.m_page.ToString();
this.m_page.Append(this.ClipBoard);
this.m_page.Append("\n");
}
public void Print()
{
Console.WriteLine("File {0} at {1}\n{2}", this.m_name, DateTime.Now.ToString(), this.m_page.ToString());
}
public void Restore()
{
this.m_page.Length = 0;
this.m_page.Append(this.m_oldpage);
}
}
Use the Command Pattern
The Program class creates an instance of the Page and Print command classes.
class Program
{
static void Main(string[] args)
{
ICommand paste = new Paste();
ICommand print = new Print();
Invoker document = new Invoker("Greetings");
document.ClipBoard = "Hello, everyone";
document.Execute(paste);
document.Execute(print);
document.Undo(paste);
document.ClipBoard = "Bonjour, mes amis";
document.Execute(paste);
document.Redo(paste);
document.Undo(paste);
document.ClipBoard = "Guten morgen, meine Freunde";
document.Redo(paste);
document.Execute(print);
document.Undo(print);
document.Log();
Console.Read();
}
An instance of the Invoker class is created and the required commands (methods) actioned.