In continuation with the series on design pattern, I am currently going
through Behavioral Patterns. Today I will write about the Command
Pattern. You can read about rest of the patterns from the following
links
Strategy
Pattern
State
Pattern
Template Method
Pattern
Chain of Responsibility
Pattern
You can read about the Structural patterns
here .
You can read about the Creational patterns
here .
The Command pattern deals with segregation of the client that requested
an operation and the object that can perform that operation. The command
pattern can support sending requests to different receivers, queuing of
requests, redo and undo functionality.
namespace PatternsConsole
{
public class CommandPattern
{
// Command
interface ICommand
{
void Execute ();
}
// ConcreteCommand
class AddCommand : ICommand
{
public Item Itm { get ; set ; }
public Category Cat { get ; set ; }
public void Execute ()
{
Itm . Add ( Cat );
Cat . Add ( Itm );
}
}
// ConcreteCommand
class DeleteCommand : ICommand
{
public Item Itm { get ; set ; }
public Category Cat { get ; set ; }
public void Execute ()
{
Itm . Delete ( Cat );
Cat . Delete ( Itm );
}
}
// Invoker
class ItemManager
{
public ICommand Command { set ; get ; }
public void Process ()
{
Command . Execute ();
}
}
// Receiver
class Item
{
private IDictionary < string , Category > categories ;
public string Desc { get ; set ; }
public Item (
string itemName )
{
Desc = itemName ;
categories = new Dictionary < string , Category >();
}
public void Add (
Category cat )
{
categories . Add (
cat . Desc ,
cat );
}
public void Delete (
Category cat )
{
categories . Remove ( cat . Desc );
}
}
// Receiver
class Category
{
private IDictionary < string , Item > items ;
public string Desc { get ; set ; }
public Category (
string catName )
{
Desc = catName ;
items = new Dictionary < string , Item >();
}
public void Add (
Item item )
{
items . Add (
item . Desc ,
item );
Console . WriteLine (
"Item '" + item . Desc + "' has been added to the '"
+ Desc + "' Category " );
}
public void Delete (
Item item )
{
items . Remove ( item . Desc );
Console . WriteLine (
"Item '" + item . Desc
+ "' has been deleted from the '" + Desc + "' Category " );
}
}
public static void Main ()
{
// Create Receiver objects
Item DVD = new Item ( "The Fountain" );
Category catDVD = new Category ( "DVD" );
// create the command object
ICommand command = new AddCommand { Itm = DVD , Cat = catDVD };
// create the invoker
ItemManager manager = new ItemManager { Command = command };
manager . Process ();
// Add an item to the CD category
DVD = new Item ( "The Wrestler" );
catDVD = new Category ( "DVD" );
command = new AddCommand { Itm = DVD , Cat = catDVD };
manager . Command = command ;
manager . Process ();
// Add an item to the Old Releases category
DVD = new Item ( "Pi" );
catDVD = new Category ( "Old Releases" );
command = new AddCommand { Itm = DVD , Cat = catDVD };
manager . Command = command ;
manager . Process ();
// Delete an item from the Old Releases category
command = new DeleteCommand { Itm = DVD , Cat = catDVD };
manager . Command = command ;
manager . Process ();
// Output:
// Item 'The Fountain' has been added to the 'DVD' Category
// Item 'The Wrestler' has been added to the 'DVD' Category
// Item 'Pi' has been added to the 'Old Releases' Category
// Item 'Pi' has been deleted from the 'Old Releases' Category
Console . ReadLine ();
}
}
}
We can use the command pattern when we have different receivers and
handle each in a different way or we want to specify and execute
commands at different times or when we want to support undo
functionality.
In my next post I will be writing about the Iterator pattern.
Comments