0% found this document useful (0 votes)
916 views29 pages

Design Patterns

Uploaded by

donepudi_4u
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
916 views29 pages

Design Patterns

Uploaded by

donepudi_4u
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd

.

Net Design Patterns 1

Singleton Design Pattern


definition
Ensure a class has only one instance and provide a global point of access to it.

UML class diagram

participants
The classes and/or objects participating in this pattern are:
• Singleton (LoadBalancer)
o defines an Instance operation that lets clients access its unique instance. Instance is a class operation.
o responsible for creating and maintaining its own unique instance.
sample code in C#
This structural code demonstrates the Singleton pattern which assures only a single instance (the singleton) of the class
can be created.

// Singleton pattern -- Structural example

using System;

namespace [Link]
{
/// <summary>
/// MainApp startup class for Structural
/// Singleton Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
// Constructor is protected -- cannot use new
Singleton s1 = [Link]();
Singleton s2 = [Link]();

// Test for same instance


if (s1 == s2)
{
[Link]("Objects are the same instance");
}

// Wait for user


[Link]();
}
}

/// <summary>
/// The 'Singleton' class
/// </summary>
class Singleton
{
private static Singleton _instance;

// Constructor is 'protected'
protected Singleton()
{
}
.Net Design Patterns 2
public static Singleton Instance()
{
// Uses lazy initialization.
// Note: this is not thread safe.
if (_instance == null)
{
_instance = new Singleton();
}

return _instance;
}
}
}

Output
Objects are the same instance

This real-world code demonstrates the Singleton pattern as a LoadBalancing object. Only a single instance (the singleton)
of the class can be created because servers may dynamically come on- or off-line and every request must go throught the
one object that has knowledge about the state of the (web) farm.

// Singleton pattern -- Real World example

using System;
using [Link];
using [Link];

namespace [Link]
{
/// <summary>
/// MainApp startup class for Real-World
/// Singleton Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
LoadBalancer b1 = [Link]();
LoadBalancer b2 = [Link]();
LoadBalancer b3 = [Link]();
LoadBalancer b4 = [Link]();

// Same instance?
if (b1 == b2 && b2 == b3 && b3 == b4)
{
[Link]("Same instance\n");
}

// Load balance 15 server requests


LoadBalancer balancer = [Link]();
for (int i = 0; i < 15; i++)
{
string server = [Link];
[Link]("Dispatch Request to: " + server);
}

// Wait for user


[Link]();
}
}

/// <summary>
.Net Design Patterns 3
/// The 'Singleton' class
/// </summary>
class LoadBalancer
{
private static LoadBalancer _instance;
private List<string> _servers = new List<string>();
private Random _random = new Random();

// Lock synchronization object


private static object syncLock = new object();

// Constructor (protected)
protected LoadBalancer()
{
// List of available servers
_servers.Add("ServerI");
_servers.Add("ServerII");
_servers.Add("ServerIII");
_servers.Add("ServerIV");
_servers.Add("ServerV");
}

public static LoadBalancer GetLoadBalancer()


{
// Support multithreaded applications through
// 'Double checked locking' pattern which (once
// the instance exists) avoids locking each
// time the method is invoked
if (_instance == null)
{
lock (syncLock)
{
if (_instance == null)
{
_instance = new LoadBalancer();
}
}
}

return _instance;
}

// Simple, but effective random load balancer


public string Server
{
get
{
int r = _random.Next(_servers.Count);
return _servers[r].ToString();
}
}
}
}

Output
Same instance

ServerIII
ServerII
ServerI
ServerII
ServerI
ServerIII
ServerI
ServerIII
ServerIV
ServerII
ServerII
.Net Design Patterns 4
ServerIII
ServerIV
ServerII
ServerIV

This .NET optimized code demonstrates the same code as above but uses more modern, built-in .NET features.

Here an elegant .NET specific solution is offered. The Singleton pattern simply uses a private constructor and a static
readonly instance variable that is lazily initialized. Thread safety is guaranteed by the compiler.

// Singleton pattern -- .NET optimized

using System;
using [Link];

namespace [Link]
{
/// <summary>
/// MainApp startup class for .NET optimized
/// Singleton Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
LoadBalancer b1 = [Link]();
LoadBalancer b2 = [Link]();
LoadBalancer b3 = [Link]();
LoadBalancer b4 = [Link]();

// Confirm these are the same instance


if (b1 == b2 && b2 == b3 && b3 == b4)
{
[Link]("Same instance\n");
}

// Next, load balance 15 requests for a server


LoadBalancer balancer = [Link]();
for (int i = 0; i < 15; i++)
{
string serverName = [Link];
[Link]("Dispatch request to: " + serverName);
}

// Wait for user


[Link]();
}
}

/// <summary>
/// The 'Singleton' class
/// </summary>
sealed class LoadBalancer
{
// Static members are 'eagerly initialized', that is,
// immediately when class is loaded for the first time.
// .NET guarantees thread safety for static initialization
private static readonly LoadBalancer _instance =
new LoadBalancer();

// Type-safe generic list of servers


private List<Server> _servers;
private Random _random = new Random();
.Net Design Patterns 5
// Note: constructor is 'private'
private LoadBalancer()
{
// Load list of available servers
_servers = new List<Server>
{
new Server{ Name = "ServerI", IP = "[Link]" },
new Server{ Name = "ServerII", IP = "[Link]" },
new Server{ Name = "ServerIII", IP = "[Link]" },
new Server{ Name = "ServerIV", IP = "[Link]" },
new Server{ Name = "ServerV", IP = "[Link]" },
};
}

public static LoadBalancer GetLoadBalancer()


{
return _instance;
}

// Simple, but effective load balancer


public Server NextServer
{
get
{
int r = _random.Next(_servers.Count);
return _servers[r];
}
}
}

/// <summary>
/// Represents a server machine
/// </summary>
class Server
{
// Gets or sets server name
public string Name { get; set; }

// Gets or sets server IP address


public string IP { get; set; }
}
}

Output
Same instance

ServerIV
ServerIV
ServerIII
ServerV
ServerII
ServerV
ServerII
ServerII
ServerI
ServerIV
ServerIV
ServerII
ServerI
ServerV
ServerIV
.Net Design Patterns 6

Abstract Factory Design Pattern


definition
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

UML class diagram

participants
The classes and/or objects participating in this pattern are:
• AbstractFactory (ContinentFactory)
o declares an interface for operations that create abstract products
• ConcreteFactory (AfricaFactory, AmericaFactory)
o implements the operations to create concrete product objects
• AbstractProduct (Herbivore, Carnivore)
o declares an interface for a type of product object
• Product (Wildebeest, Lion, Bison, Wolf)
o defines a product object to be created by the corresponding concrete factory
o implements the AbstractProduct interface
• Client (AnimalWorld)
o uses interfaces declared by AbstractFactory and AbstractProduct classes
sample code in C#
This structural code demonstrates the Abstract Factory pattern creating parallel hierarchies of objects. Object creation has
been abstracted and there is no need for hard-coded class names in the client code.
.Net Design Patterns 7
// Abstract Factory pattern -- Structural example

using System;

namespace [Link]
{
/// <summary>
/// MainApp startup class for Structural
/// Abstract Factory Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
public static void Main()
{
// Abstract factory #1
AbstractFactory factory1 = new ConcreteFactory1();
Client client1 = new Client(factory1);
[Link]();

// Abstract factory #2
AbstractFactory factory2 = new ConcreteFactory2();
Client client2 = new Client(factory2);
[Link]();

// Wait for user input


[Link]();
}
}

/// <summary>
/// The 'AbstractFactory' abstract class
/// </summary>
abstract class AbstractFactory
{
public abstract AbstractProductA CreateProductA();
public abstract AbstractProductB CreateProductB();
}

/// <summary>
/// The 'ConcreteFactory1' class
/// </summary>
class ConcreteFactory1 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA1();
}
public override AbstractProductB CreateProductB()
{
return new ProductB1();
}
}

/// <summary>
/// The 'ConcreteFactory2' class
/// </summary>
class ConcreteFactory2 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA2();
}
public override AbstractProductB CreateProductB()
{
return new ProductB2();
.Net Design Patterns 8
}
}

/// <summary>
/// The 'AbstractProductA' abstract class
/// </summary>
abstract class AbstractProductA
{
}

/// <summary>
/// The 'AbstractProductB' abstract class
/// </summary>
abstract class AbstractProductB
{
public abstract void Interact(AbstractProductA a);
}

/// <summary>
/// The 'ProductA1' class
/// </summary>
class ProductA1 : AbstractProductA
{
}

/// <summary>
/// The 'ProductB1' class
/// </summary>
class ProductB1 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
[Link]([Link]().Name +
" interacts with " + [Link]().Name);
}
}

/// <summary>
/// The 'ProductA2' class
/// </summary>
class ProductA2 : AbstractProductA
{
}

/// <summary>
/// The 'ProductB2' class
/// </summary>
class ProductB2 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
[Link]([Link]().Name +
" interacts with " + [Link]().Name);
}
}

/// <summary>
/// The 'Client' class. Interaction environment for the products.
/// </summary>
class Client
{
private AbstractProductA _abstractProductA;
private AbstractProductB _abstractProductB;

// Constructor
public Client(AbstractFactory factory)
{
_abstractProductB = [Link]();
.Net Design Patterns 9
_abstractProductA = [Link]();
}

public void Run()


{
_abstractProductB.Interact(_abstractProductA);
}
}
}

Output
ProductB1 interacts with ProductA1
ProductB2 interacts with ProductA2

This real-world code demonstrates the creation of different animal worlds for a computer game using different factories.
Although the animals created by the Continent factories are different, the interactions among the animals remain the
same.

// Abstract Factory pattern -- Real World example

using System;

namespace [Link]
{
/// <summary>
/// MainApp startup class for Real-World
/// Abstract Factory Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
public static void Main()
{
// Create and run the African animal world
ContinentFactory africa = new AfricaFactory();
AnimalWorld world = new AnimalWorld(africa);
[Link]();

// Create and run the American animal world


ContinentFactory america = new AmericaFactory();
world = new AnimalWorld(america);
[Link]();

// Wait for user input


[Link]();
}
}

/// <summary>
/// The 'AbstractFactory' abstract class
/// </summary>
abstract class ContinentFactory
{
public abstract Herbivore CreateHerbivore();
public abstract Carnivore CreateCarnivore();
}

/// <summary>
/// The 'ConcreteFactory1' class
/// </summary>
class AfricaFactory : ContinentFactory
{
.Net Design Patterns 10
public override Herbivore CreateHerbivore()
{
return new Wildebeest();
}
public override Carnivore CreateCarnivore()
{
return new Lion();
}
}

/// <summary>
/// The 'ConcreteFactory2' class
/// </summary>
class AmericaFactory : ContinentFactory
{
public override Herbivore CreateHerbivore()
{
return new Bison();
}
public override Carnivore CreateCarnivore()
{
return new Wolf();
}
}

/// <summary>
/// The 'AbstractProductA' abstract class
/// </summary>
abstract class Herbivore
{
}

/// <summary>
/// The 'AbstractProductB' abstract class
/// </summary>
abstract class Carnivore
{
public abstract void Eat(Herbivore h);
}

/// <summary>
/// The 'ProductA1' class
/// </summary>
class Wildebeest : Herbivore
{
}

/// <summary>
/// The 'ProductB1' class
/// </summary>
class Lion : Carnivore
{
public override void Eat(Herbivore h)
{
// Eat Wildebeest
[Link]([Link]().Name +
" eats " + [Link]().Name);
}
}

/// <summary>
/// The 'ProductA2' class
/// </summary>
class Bison : Herbivore
{
}

/// <summary>
/// The 'ProductB2' class
.Net Design Patterns 11
/// </summary>
class Wolf : Carnivore
{
public override void Eat(Herbivore h)
{
// Eat Bison
[Link]([Link]().Name +
" eats " + [Link]().Name);
}
}

/// <summary>
/// The 'Client' class
/// </summary>
class AnimalWorld
{
private Herbivore _herbivore;
private Carnivore _carnivore;

// Constructor
public AnimalWorld(ContinentFactory factory)
{
_carnivore = [Link]();
_herbivore = [Link]();
}

public void RunFoodChain()


{
_carnivore.Eat(_herbivore);
}
}
}

Output
Lion eats Wildebeest
Wolf eats Bison

Factory Method Design Pattern

definition
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a
class defer instantiation to subclasses.

UML class diagram

participants
The classes and/or objects participating in this pattern are:
• Product (Page)
o defines the interface of objects the factory method creates
• ConcreteProduct (SkillsPage, EducationPage, ExperiencePage)
.Net Design Patterns 12
o implements the Product interface
• Creator (Document)
o declares the factory method, which returns an object of type Product. Creator may also define a default
implementation of the factory method that returns a default ConcreteProduct object.
o may call the factory method to create a Product object.
• ConcreteCreator (Report, Resume)
o overrides the factory method to return an instance of a ConcreteProduct.
sample code in C#
This structural code demonstrates the Factory method offering great flexibility in creating different objects. The Abstract
class may provide a default object, but each subclass can instantiate an extended version of the object.

// Factory Method pattern -- Structural example

using System;

namespace [Link]
{
/// <summary>
/// MainApp startup class for Structural
/// Factory Method Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
// An array of creators
Creator[] creators = new Creator[2];

creators[0] = new ConcreteCreatorA();


creators[1] = new ConcreteCreatorB();

// Iterate over creators and create products


foreach (Creator creator in creators)
{
Product product = [Link]();
[Link]("Created {0}",
[Link]().Name);
}

// Wait for user


[Link]();
}
}

/// <summary>
/// The 'Product' abstract class
/// </summary>
abstract class Product
{
}

/// <summary>
/// A 'ConcreteProduct' class
/// </summary>
class ConcreteProductA : Product
{
}

/// <summary>
/// A 'ConcreteProduct' class
/// </summary>
class ConcreteProductB : Product
{
}
.Net Design Patterns 13
/// <summary>
/// The 'Creator' abstract class
/// </summary>
abstract class Creator
{
public abstract Product FactoryMethod();
}

/// <summary>
/// A 'ConcreteCreator' class
/// </summary>
class ConcreteCreatorA : Creator
{
public override Product FactoryMethod()
{
return new ConcreteProductA();
}
}

/// <summary>
/// A 'ConcreteCreator' class
/// </summary>
class ConcreteCreatorB : Creator
{
public override Product FactoryMethod()
{
return new ConcreteProductB();
}
}
}

Output
Created ConcreteProductA
Created ConcreteProductB

This real-world code demonstrates the Factory method offering flexibility in creating different documents. The derived
Document classes Report and Resume instantiate extended versions of the Document class. Here, the Factory Method is
called in the constructor of the Document base class.

// Factory Method pattern -- Real World example

using System;
using [Link];

namespace [Link]
{
/// <summary>
/// MainApp startup class for Real-World
/// Factory Method Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
// Note: constructors call Factory Method
Document[] documents = new Document[2];

documents[0] = new Resume();


documents[1] = new Report();

// Display document pages


foreach (Document document in documents)
.Net Design Patterns 14
{
[Link]("\n" + [Link]().Name + "--");
foreach (Page page in [Link])
{
[Link](" " + [Link]().Name);
}
}

// Wait for user


[Link]();
}
}

/// <summary>
/// The 'Product' abstract class
/// </summary>
abstract class Page
{
}

/// <summary>
/// A 'ConcreteProduct' class
/// </summary>
class SkillsPage : Page
{
}

/// <summary>
/// A 'ConcreteProduct' class
/// </summary>
class EducationPage : Page
{
}

/// <summary>
/// A 'ConcreteProduct' class
/// </summary>
class ExperiencePage : Page
{
}

/// <summary>
/// A 'ConcreteProduct' class
/// </summary>
class IntroductionPage : Page
{
}

/// <summary>
/// A 'ConcreteProduct' class
/// </summary>
class ResultsPage : Page
{
}

/// <summary>
/// A 'ConcreteProduct' class
/// </summary>
class ConclusionPage : Page
{
}

/// <summary>
/// A 'ConcreteProduct' class
/// </summary>
class SummaryPage : Page
{
}
.Net Design Patterns 15
/// <summary>
/// A 'ConcreteProduct' class
/// </summary>
class BibliographyPage : Page
{
}

/// <summary>
/// The 'Creator' abstract class
/// </summary>
abstract class Document
{
private List<Page> _pages = new List<Page>();

// Constructor calls abstract Factory method


public Document()
{
[Link]();
}

public List<Page> Pages


{
get { return _pages; }
}

// Factory Method
public abstract void CreatePages();
}

/// <summary>
/// A 'ConcreteCreator' class
/// </summary>
class Resume : Document
{
// Factory Method implementation
public override void CreatePages()
{
[Link](new SkillsPage());
[Link](new EducationPage());
[Link](new ExperiencePage());
}
}

/// <summary>
/// A 'ConcreteCreator' class
/// </summary>
class Report : Document
{
// Factory Method implementation
public override void CreatePages()
{
[Link](new IntroductionPage());
[Link](new ResultsPage());
[Link](new ConclusionPage());
[Link](new SummaryPage());
[Link](new BibliographyPage());
}
}
}

Output
Resume -------
SkillsPage
EducationPage
ExperiencePage

Report -------
IntroductionPage
.Net Design Patterns 16
ResultsPage
ConclusionPage
SummaryPage
BibliographyPage

Prototype Design Pattern

definition
Specify the kind of objects to create using a prototypical instance, and create new objects by copying this prototype.

UML class diagram

participants
The classes and/or objects participating in this pattern are:
• Prototype (ColorPrototype)
o declares an interface for cloning itself
• ConcretePrototype (Color)
o implements an operation for cloning itself
• Client (ColorManager)
o creates a new object by asking a prototype to clone itself
sample code in C#
This structural code demonstrates the Prototype pattern in which new objects are created by copying pre-existing objects
(prototypes) of the same class.

// Prototype pattern -- Structural example

using System;

namespace [Link]
{
/// <summary>
/// MainApp startup class for Structural
/// Prototype Design Pattern.
.Net Design Patterns 17
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
// Create two instances and clone each

ConcretePrototype1 p1 = new ConcretePrototype1("I");


ConcretePrototype1 c1 = (ConcretePrototype1)[Link]();
[Link]("Cloned: {0}", [Link]);

ConcretePrototype2 p2 = new ConcretePrototype2("II");


ConcretePrototype2 c2 = (ConcretePrototype2)[Link]();
[Link]("Cloned: {0}", [Link]);

// Wait for user


[Link]();
}
}

/// <summary>
/// The 'Prototype' abstract class
/// </summary>
abstract class Prototype
{
private string _id;

// Constructor
public Prototype(string id)
{
this._id = id;
}

// Gets id
public string Id
{
get { return _id; }
}

public abstract Prototype Clone();


}

/// <summary>
/// A 'ConcretePrototype' class
/// </summary>
class ConcretePrototype1 : Prototype
{
// Constructor
public ConcretePrototype1(string id)
: base(id)
{
}

// Returns a shallow copy


public override Prototype Clone()
{
return (Prototype)[Link]();
}
}

/// <summary>
/// A 'ConcretePrototype' class
/// </summary>
class ConcretePrototype2 : Prototype
{
// Constructor
.Net Design Patterns 18
public ConcretePrototype2(string id)
: base(id)
{
}

// Returns a shallow copy


public override Prototype Clone()
{
return (Prototype)[Link]();
}
}
}

Output
Cloned: I
Cloned: II

This real-world code demonstrates the Prototype pattern in which new Color objects are created by copying pre-existing,
user-defined Colors of the same type.

// Prototype pattern -- Real World example

using System;
using [Link];

namespace [Link]
{
/// <summary>
/// MainApp startup class for Real-World
/// Prototype Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
ColorManager colormanager = new ColorManager();

// Initialize with standard colors


colormanager["red"] = new Color(255, 0, 0);
colormanager["green"] = new Color(0, 255, 0);
colormanager["blue"] = new Color(0, 0, 255);

// User adds personalized colors


colormanager["angry"] = new Color(255, 54, 0);
colormanager["peace"] = new Color(128, 211, 128);
colormanager["flame"] = new Color(211, 34, 20);

// User clones selected colors


Color color1 = colormanager["red"].Clone() as Color;
Color color2 = colormanager["peace"].Clone() as Color;
Color color3 = colormanager["flame"].Clone() as Color;

// Wait for user


[Link]();
}
}

/// <summary>
/// The 'Prototype' abstract class
/// </summary>
abstract class ColorPrototype
{
public abstract ColorPrototype Clone();
.Net Design Patterns 19
}

/// <summary>
/// The 'ConcretePrototype' class
/// </summary>
class Color : ColorPrototype
{
private int _red;
private int _green;
private int _blue;

// Constructor
public Color(int red, int green, int blue)
{
this._red = red;
this._green = green;
this._blue = blue;
}

// Create a shallow copy


public override ColorPrototype Clone()
{
[Link](
"Cloning color RGB: {0,3},{1,3},{2,3}",
_red, _green, _blue);

return [Link]() as ColorPrototype;


}
}

/// <summary>
/// Prototype manager
/// </summary>
class ColorManager
{
private Dictionary<string, ColorPrototype> _colors =
new Dictionary<string, ColorPrototype>();

// Indexer
public ColorPrototype this[string key]
{
get { return _colors[key]; }
set { _colors.Add(key, value); }
}
}
}

Output
Cloning color RGB: 255, 0, 0
Cloning color RGB: 128,211,128
Cloning color RGB: 211, 34, 20

Decorator Design Pattern

definition
Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing
for extending functionality.

UML class diagram


.Net Design Patterns 20

participants
The classes and/or objects participating in this pattern are:
• Component (LibraryItem)
o defines the interface for objects that can have responsibilities added to them dynamically.
• ConcreteComponent (Book, Video)
o defines an object to which additional responsibilities can be attached.
• Decorator (Decorator)
o maintains a reference to a Component object and defines an interface that conforms to Component's interface.
• ConcreteDecorator (Borrowable)
o adds responsibilities to the component.
sample code in C#
This structural code demonstrates the Decorator pattern which dynamically adds extra functionality to an existing object.
// Decorator pattern -- Structural example

using System;

namespace [Link]
{
/// <summary>
/// MainApp startup class for Structural
/// Decorator Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
// Create ConcreteComponent and two Decorators
ConcreteComponent c = new ConcreteComponent();
ConcreteDecoratorA d1 = new ConcreteDecoratorA();
ConcreteDecoratorB d2 = new ConcreteDecoratorB();

// Link decorators
[Link](c);
[Link](d1);

[Link]();
.Net Design Patterns 21
// Wait for user
[Link]();
}
}

/// <summary>
/// The 'Component' abstract class
/// </summary>
abstract class Component
{
public abstract void Operation();
}

/// <summary>
/// The 'ConcreteComponent' class
/// </summary>
class ConcreteComponent : Component
{
public override void Operation()
{
[Link]("[Link]()");
}
}

/// <summary>
/// The 'Decorator' abstract class
/// </summary>
abstract class Decorator : Component
{
protected Component component;

public void SetComponent(Component component)


{
[Link] = component;
}

public override void Operation()


{
if (component != null)
{
[Link]();
}
}
}

/// <summary>
/// The 'ConcreteDecoratorA' class
/// </summary>
class ConcreteDecoratorA : Decorator
{
public override void Operation()
{
[Link]();
[Link]("[Link]()");
}
}

/// <summary>
/// The 'ConcreteDecoratorB' class
/// </summary>
class ConcreteDecoratorB : Decorator
{
public override void Operation()
{
[Link]();
AddedBehavior();
[Link]("[Link]()");
}
.Net Design Patterns 22
void AddedBehavior()
{
}
}
}

Output
[Link]()
[Link]()
[Link]()

This real-world code demonstrates the Decorator pattern in which 'borrowable' functionality is added to existing library
items (books and videos).

// Decorator pattern -- Real World example

using System;
using [Link];

namespace [Link]
{
/// <summary>
/// MainApp startup class for Real-World
/// Decorator Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
// Create book
Book book = new Book("Worley", "Inside [Link]", 10);
[Link]();

// Create video
Video video = new Video("Spielberg", "Jaws", 23, 92);
[Link]();

// Make video borrowable, then borrow and display


[Link]("\nMaking video borrowable:");

Borrowable borrowvideo = new Borrowable(video);


[Link]("Customer #1");
[Link]("Customer #2");

[Link]();

// Wait for user


[Link]();
}
}

/// <summary>
/// The 'Component' abstract class
/// </summary>
abstract class LibraryItem
{
private int _numCopies;

// Property
public int NumCopies
{
get { return _numCopies; }
set { _numCopies = value; }
.Net Design Patterns 23
}

public abstract void Display();


}

/// <summary>
/// The 'ConcreteComponent' class
/// </summary>
class Book : LibraryItem
{
private string _author;
private string _title;

// Constructor
public Book(string author, string title, int numCopies)
{
this._author = author;
this._title = title;
[Link] = numCopies;
}

public override void Display()


{
[Link]("\nBook ------ ");
[Link](" Author: {0}", _author);
[Link](" Title: {0}", _title);
[Link](" # Copies: {0}", NumCopies);
}
}

/// <summary>
/// The 'ConcreteComponent' class
/// </summary>
class Video : LibraryItem
{
private string _director;
private string _title;
private int _playTime;

// Constructor
public Video(string director, string title,
int numCopies, int playTime)
{
this._director = director;
this._title = title;
[Link] = numCopies;
this._playTime = playTime;
}

public override void Display()


{
[Link]("\nVideo ----- ");
[Link](" Director: {0}", _director);
[Link](" Title: {0}", _title);
[Link](" # Copies: {0}", NumCopies);
[Link](" Playtime: {0}\n", _playTime);
}
}

/// <summary>
/// The 'Decorator' abstract class
/// </summary>
abstract class Decorator : LibraryItem
{
protected LibraryItem libraryItem;

// Constructor
public Decorator(LibraryItem libraryItem)
{
.Net Design Patterns 24
[Link] = libraryItem;
}

public override void Display()


{
[Link]();
}
}

/// <summary>
/// The 'ConcreteDecorator' class
/// </summary>
class Borrowable : Decorator
{
protected List<string> borrowers = new List<string>();

// Constructor
public Borrowable(LibraryItem libraryItem)
: base(libraryItem)
{
}

public void BorrowItem(string name)


{
[Link](name);
[Link]--;
}

public void ReturnItem(string name)


{
[Link](name);
[Link]++;
}

public override void Display()


{
[Link]();

foreach (string borrower in borrowers)


{
[Link](" borrower: " + borrower);
}
}
}
}

Output
Book ------
Author: Worley
Title: Inside [Link]
# Copies: 10

Video -----
Director: Spielberg
Title: Jaws
# Copies: 23
Playtime: 92

Making video borrowable:

Video -----
Director: Spielberg
Title: Jaws
# Copies: 21
Playtime: 92

borrower: Customer #1
.Net Design Patterns 25
borrower: Customer #2

Command Design Pattern


definition
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log
requests, and support undoable operations.
UML class diagram

participants
The classes and/or objects participating in this pattern are:
• Command (Command)
o declares an interface for executing an operation
• ConcreteCommand (CalculatorCommand)
o defines a binding between a Receiver object and an action
o implements Execute by invoking the corresponding operation(s) on Receiver
• Client (CommandApp)
o creates a ConcreteCommand object and sets its receiver
• Invoker (User)
o asks the command to carry out the request
• Receiver (Calculator)
o knows how to perform the operations associated with carrying out the request.
sample code in C#
This structural code demonstrates the Command pattern which stores requests as objects allowing clients to execute or
playback the requests.
// Command pattern -- Structural example

using System;

namespace [Link]
{
/// <summary>
/// MainApp startup class for Structural
/// Command Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
// Create receiver, command, and invoker
Receiver receiver = new Receiver();
.Net Design Patterns 26
Command command = new ConcreteCommand(receiver);
Invoker invoker = new Invoker();

// Set and execute command


[Link](command);
[Link]();

// Wait for user


[Link]();
}
}

/// <summary>
/// The 'Command' abstract class
/// </summary>
abstract class Command
{
protected Receiver receiver;

// Constructor
public Command(Receiver receiver)
{
[Link] = receiver;
}

public abstract void Execute();


}

/// <summary>
/// The 'ConcreteCommand' class
/// </summary>
class ConcreteCommand : Command
{
// Constructor
public ConcreteCommand(Receiver receiver) :
base(receiver)
{
}

public override void Execute()


{
[Link]();
}
}

/// <summary>
/// The 'Receiver' class
/// </summary>
class Receiver
{
public void Action()
{
[Link]("Called [Link]()");
}
}

/// <summary>
/// The 'Invoker' class
/// </summary>
class Invoker
{
private Command _command;

public void SetCommand(Command command)


{
this._command = command;
}

public void ExecuteCommand()


.Net Design Patterns 27
{
_command.Execute();
}
}
}

Output
Called [Link]()

using System;
using [Link];

namespace [Link]
{
/// <summary>
/// MainApp startup class for Real-World
/// Command Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
// Create user and let her compute
User user = new User();

// User presses calculator buttons


[Link]('+', 100);
[Link]('-', 50);
[Link]('*', 10);
[Link]('/', 2);

// Undo 4 commands
[Link](4);

// Redo 3 commands
[Link](3);

// Wait for user


[Link]();
}
}

/// <summary>
/// The 'Command' abstract class
/// </summary>
abstract class Command
{
public abstract void Execute();
public abstract void UnExecute();
}

/// <summary>
/// The 'ConcreteCommand' class
/// </summary>
class CalculatorCommand : Command
{
private char _operator;
private int _operand;
private Calculator _calculator;

// Constructor
public CalculatorCommand(Calculator calculator,
char @operator, int operand)
{
.Net Design Patterns 28
this._calculator = calculator;
this._operator = @operator;
this._operand = operand;
}

// Gets operator
public char Operator
{
set { _operator = value; }
}

// Get operand
public int Operand
{
set { _operand = value; }
}

// Execute new command


public override void Execute()
{
_calculator.Operation(_operator, _operand);
}

// Unexecute last command


public override void UnExecute()
{
_calculator.Operation(Undo(_operator), _operand);
}

// Returns opposite operator for given operator


private char Undo(char @operator)
{
switch (@operator)
{
case '+': return '-';
case '-': return '+';
case '*': return '/';
case '/': return '*';
default: throw new
ArgumentException("@operator");
}
}
}

/// <summary>
/// The 'Receiver' class
/// </summary>
class Calculator
{
private int _curr = 0;

public void Operation(char @operator, int operand)


{
switch (@operator)
{
case '+': _curr += operand; break;
case '-': _curr -= operand; break;
case '*': _curr *= operand; break;
case '/': _curr /= operand; break;
}
[Link](
"Current value = {0,3} (following {1} {2})",
_curr, @operator, operand);
}
}

/// <summary>
/// The 'Invoker' class
/// </summary>
.Net Design Patterns 29
class User
{
// Initializers
private Calculator _calculator = new Calculator();
private List<Command> _commands = new List<Command>();
private int _current = 0;

public void Redo(int levels)


{
[Link]("\n---- Redo {0} levels ", levels);
// Perform redo operations
for (int i = 0; i < levels; i++)
{
if (_current < _commands.Count - 1)
{
Command command = _commands[_current++];
[Link]();
}
}
}
public void Undo(int levels)
{
[Link]("\n---- Undo {0} levels ", levels);
// Perform undo operations
for (int i = 0; i < levels; i++)
{
if (_current > 0)
{
Command command = _commands[--_current] as Command;
[Link]();
}
}
}
public void Compute(char @operator, int operand)
{
// Create command operation and execute it
Command command = new CalculatorCommand(
_calculator, @operator, operand);
[Link]();

// Add command to undo list


_commands.Add(command);
_current++;
}
}
}

You might also like