Friday, December 14, 2007

GoF Design Patterns (simplified)






Creational patterns


1. Abstract Factory

2. Builder

3. Factory Method

4. Prototype

5. Singleton

 

Structural patterns

6. Adapter

7. Bridge

8. Composite

9. Decorator

10. Façade

11. Flyweight

12. Proxy

 

Behavioral patterns

13. Chain Of Responsibility

14. Command

15. Interpreter

16. Iterator

17. Mediator

18. Memento

19. Observer

20. State

21. Strategy

22. Template

23. Visitor

 


Creational patterns


Abstract Factory
A way passing a request between a chain of objects
Definition
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

Usage
Very high

Participants
AbstractFactory

  • declares an interface for operations that create abstract products

abstract class ContinentFactory

{

public abstract Herbivore CreateHerbivore();

public abstract Carnivore CreateCarnivore();

}
ConcreteFactory

  • implements the operations to create concrete product objects

class AfricaFactory : ContinentFactory

{

public override Herbivore CreateHerbivore()

{

return new Wildebeest();

}

public override Carnivore CreateCarnivore()

{

return new Lion();

}

}
AbstractProduct

  • declares an interface for a type of product object

abstract class Herbivore

{

}

abstract class Carnivore

{

public abstract void Eat(Herbivore h);

}
Product

  • defines a product object to be created by the corresponding concrete factory
  • implements the AbstractProduct interface
class Lion : Carnivore

{

public override void Eat(Herbivore h)

{

// Eat Wildebeest

Console.WriteLine(this.GetType().Name + " eats " + h.GetType().Name);

}

}
Client
class AnimalWorld

{

private Herbivore herbivore;

private Carnivore carnivore;

// Constructor

public AnimalWorld(ContinentFactory factory)

{

carnivore = factory.CreateCarnivore();

herbivore = factory.CreateHerbivore();

}

public void RunFoodChain()

{

carnivore.Eat(herbivore);

}

}
public static void Main()

{

// Create and run the Africa animal world

ContinentFactory africa = new AfricaFactory();

AnimalWorld world = new AnimalWorld(africa);

world.RunFoodChain();

}

Builder
Separates object construction from its representation
Definition
Separate the construction of a complex object from its representation so that the same construction process can create different representations.

Usage
Medium Low

Participants
Director

  • constructs an object using the Builder interface
class Shop

{

public void Construct(VehicleBuilder vehicleBuilder)

{

vehicleBuilder.BuildFrame();

vehicleBuilder.BuildEngine();

}

}
Builder

  • specifies an abstract interface for creating parts of a Product object
abstract class VehicleBuilder

{

protected Vehicle vehicle;

// Property

public Vehicle Vehicle

{

get{ return vehicle; }

}

public abstract void BuildFrame();

public abstract void BuildEngine();

}
ConcreteBuilder

  • constructs and assembles parts of the product by implementing the Builder interface
  • defines and keeps track of the representation it creates
  • provides an interface for retrieving the product
1.

class MotorCycleBuilder : VehicleBuilder

{

public override void BuildFrame()

{

vehicle = new Vehicle("MotorCycle");

vehicle["frame"] = "MotorCycle Frame";

}

public override void BuildEngine()

{

vehicle["engine"] = "500 cc";

}

}

2.

class CarBuilder : VehicleBuilder

{

public override void BuildFrame()

{

vehicle = new Vehicle("Car");

vehicle["frame"] = "Car Frame";

}

public override void BuildEngine()

{

vehicle["engine"] = "2500 cc";

}

}



Product

  • represents the complex object under construction. ConcreteBuilder builds the product's internal representation and defines the process by which it's assembled
  • includes classes that define the constituent parts, including interfaces for assembling the parts into the final result
class Vehicle

{

private string type;

private Hashtable parts = new Hashtable();

public Vehicle(string type)

{

this.type = type;

}

public object this[string key]

{

get{ return parts[key]; }

set{ parts[key] = value; }

}

public void Show()

{

Console.WriteLine("\n---------------------------");

Console.WriteLine("Vehicle Type: {0}", type);

Console.WriteLine(" Frame : {0}", parts["frame"]);

Console.WriteLine(" Engine : {0}", parts["engine"]);

}

}
public static void Main()

{

// Create shop with vehicle builders

Shop shop = new Shop();

VehicleBuilder b2 = new CarBuilder();

VehicleBuilder b3 = new MotorCycleBuilder();

// Construct and display vehicles

shop.Construct(b1);

b1.Vehicle.Show();

shop.Construct(b2);

b2.Vehicle.Show();

}

Factory Method
Creates an instance of several derived classes
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.

Usage
High

Participants
Product
abstract class Page

{

}
ConcreteProduct

  • implements the Product interface
1.
class SkillsPage : Page

{

}

2.
class EducationPage : Page

{

}

3.
class ConclusionPage : Page

{

}

Creator

  • 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.
  • may call the factory method to create a Product object.

abstract class Document

{

private ArrayList pages = new ArrayList();

public Document()

{

this.CreatePages();

}

public ArrayList Pages

{

get{ return pages; }

}

public abstract void CreatePages();

}
ConcreteCreator

  • overrides the factory method to return an instance of a ConcreteProduct.
1.
class Resume : Document

{

public override void CreatePages()

{

Pages.Add(new SkillsPage());

Pages.Add(new EducationPage());

}

}

2.

class Report : Document

{

public override void CreatePages()

{

Pages.Add(new SkillsPage());

Pages.Add(new EducationPage());

Pages.Add(new ConclusionPage());

}

}
public static void Main()

{

Document[] documents = new Document[2];

documents[0] = new Resume();

documents[1] = new Report();

}

Prototype
A fully initialized instance to be copied or cloned
Definition
Specify the kind of objects to create using a prototypical instance, and create new objects by copying this prototype.

Cloning is an important aspect of it.

Usage
Medium

Participants
Prototype

  • declares an interface for cloning itself
abstract class ColorPrototype

{

public abstract ColorPrototype Clone();

}



ConcretePrototype

  • implements an operation for cloning itself
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()

{

return this.MemberwiseClone() as ColorPrototype;

}

}



Client/PrototypeManager

  • creates a new object by asking a prototype to clone itself
class ColorManager

{

Hashtable colors = new Hashtable();

// Indexer

public ColorPrototype this[string name]

{

get

{

return colors[name] as ColorPrototype;

}

set

{

colors.Add(name, value);

}

}

}

static void Main()

{

ColorManager colormanager = new ColorManager();

// Initialize with standard colors

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

// User adds personalized colors

colormanager["peace"] = new Color(128, 211, 128);

Color color;

// User uses selected colors

string name = "red";

color = colormanager[name].Clone() as Color;

name = "peace";

color = colormanager[name].Clone() as Color;

}

Singleton
A class of which only a single instance can be created
Definition
Ensure a class has only one instance and provide a global point of access to it.

Usage
Medium High

Participants
Singleton

  • defines an Instance operation that lets clients access its unique instance. Instance is a class operation.
  • responsible for creating and maintaining its own unique instance.
class LoadBalancer

{

private static LoadBalancer instance;

private ArrayList servers = new ArrayList();

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");

}

public static LoadBalancer GetLoadBalancer()

{

// 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();

}

}

}

static void Main()

{

LoadBalancer b1 = LoadBalancer.GetLoadBalancer();

LoadBalancer b2 = LoadBalancer.GetLoadBalancer();

LoadBalancer b3 = LoadBalancer.GetLoadBalancer();

// Same instance?

if (b1 == b2 && b2 == b3)

{

Console.WriteLine("Same instance\n");

}

// All are the same instance -- use b1 arbitrarily - Load balance 15 server requests

for (int i = 0; i < 15; i++)

{

Console.WriteLine(b1.Server);

}

}

Structural patterns


Adapter
Match interfaces of different classes
Definition
Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.

Usage
Medium high

Participants
Target

  • defines the domain-specific interface that Client uses.
class Compound

{

protected string name;

protected float boilingPoint;

protected string molecularFormula;

public Compound(string name)

{

this.name = name;

}

public virtual void Display()

{

Console.WriteLine("\nCompound: {0} ------ ", name);

}

}
Adapter

  • adapts the interface Adaptee to the Target interface.
class RichCompound : Compound

{

private ChemicalDatabank bank;

public RichCompound(string name) : base(name)

{

}

public override void Display()

{

// Adaptee

bank = new ChemicalDatabank();

boilingPoint = bank.GetCriticalPoint(name, "B");

meltingPoint = bank.GetCriticalPoint(name, "M");

molecularFormula = bank.GetMolecularStructure(name);

}

}
Adaptee

  • defines an existing interface that needs adapting.
class ChemicalDatabank

{

// The Databank 'legacy API'

public float GetCriticalPoint(string compound, string point)

{

float temperature = 0.0F;

if (point == "M") // Melting Point

{

switch (compound.ToLower())

{

case "water" : temperature = 0.0F; break;

case "benzene" : temperature = 5.5F; break;

}

}

else // Boiling Point

{

switch (compound.ToLower())

{

case "water" : temperature = 100.0F; break;

case "benzene" : temperature = 80.1F; break;

}

}

return temperature;

}

public string GetMolecularStructure(string compound)

{

string structure = "";

switch (compound.ToLower())

{

case "water" : structure = "H20"; break;

case "benzene" : structure = "C6H6"; break;

}

return structure;

}

}
static void Main()

{

// Non-adapted chemical compound

Compound stuff = new Compound("Unknown");

stuff.Display();

// Adapted chemical compounds

Compound water = new RichCompound("Water");

water.Display();

Compound benzene = new RichCompound("Benzene");

benzene.Display();

}

Bridge
Separates an object's interface from its implementation
Definition
Decouple an abstraction from its implementation so that the two can vary independently.

Usage
Medium

Participants
Abstraction

  • defines the abstraction's interface.
  • maintains a reference to an object of type Implementor.
class CustomersBase

{

private DataObject dataObject;

protected string group;

public CustomersBase(string group)

{

this.group = group;

}

// Property

public DataObject Data

{

set{ dataObject = value; }

get{ return dataObject; }

}

public virtual void Next()

{

dataObject.NextRecord();

}

public virtual void New(string name)

{

dataObject.NewRecord(name);

}

public virtual void Show()

{

dataObject.ShowRecord();

}

public virtual void ShowAll()

{

Console.WriteLine("Customer Group: " + group);

dataObject.ShowAllRecords();

}

}

RefinedAbstraction

  • extends the interface defined by Abstraction.
class Customers : CustomersBase

{

// Constructor

public Customers(string group) : base(group)

{

}

public override void ShowAll()

{

Console.WriteLine ("------------------------");

base.ShowAll();

Console.WriteLine ("------------------------");

}

}

Implementor

  • defines the interface for implementation classes. This interface doesn't have to correspond exactly to Abstraction's interface; in fact the two interfaces can be quite different. Typically the Implementation interface provides only primitive operations, and Abstraction defines higher-level operations based on these primitives.
abstract class DataObject

{

public abstract void NextRecord();

public abstract void PriorRecord();

public abstract void NewRecord(string name);

public abstract void DeleteRecord(string name);

public abstract void ShowRecord();

public abstract void ShowAllRecords();

}
ConcreteImplementor

  • implements the Implementor interface and defines its concrete implementation.
class CustomersData : DataObject

{

private ArrayList customers = new ArrayList();

private int current = 0;

public CustomersData()

{

// Loaded from a database

customers.Add("Jim Jones");

customers.Add("Samual Jackson");

}

public override void NextRecord()

{

if (current <= customers.Count - 1)

{

current++;

}

}

public override void NewRecord(string name)

{

customers.Add(name);

}

public override void ShowRecord()

{

Console.WriteLine(customers[current]);

}

public override void ShowAllRecords()

{

foreach (string name in customers)

{

Console.WriteLine(" " + name);

}

}

}
static void Main()

{

// Create RefinedAbstraction

Customers customers =

new Customers("Chicago");

// Set ConcreteImplementor

customers.Data = new CustomersData();

// Exercise the bridge

customers.Show();

customers.Next();

customers.Show();

customers.Next();

customers.Show();

customers.New("Henry Velasquez");

customers.ShowAll();

// Wait for user

Console.Read();

}

Composite
A tree structure of simple and composite objects
Definition
Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.

Usage
Medium High

Participants
Component

  • declares the interface for objects in the composition.
  • implements default behavior for the interface common to all classes, as appropriate.
  • declares an interface for accessing and managing its child components.
  • (optional) defines an interface for accessing a component's parent in the recursive structure, and implements it if that's appropriate.
abstract class DrawingElement

{

protected string name;

// Constructor

public DrawingElement(string name)

{

this.name = name;

}

public abstract void Add(DrawingElement d);

public abstract void Remove(DrawingElement d);

public abstract void Display(int indent);

}
Leaf

  • Represents leaf objects in the composition. A leaf has no children.
  • Defines behavior for primitive objects in the composition.
class PrimitiveElement : DrawingElement

{

// Constructor

public PrimitiveElement(string name) : base(name)

{

}

public override void Add(DrawingElement c)

{

Console.WriteLine("Cannot add to a PrimitiveElement");

}

public override void Remove(DrawingElement c)

{

Console.WriteLine("Cannot remove from a PrimitiveElement");

}

public override void Display(int indent)

{

Console.WriteLine(new String('-', indent) + " " + name);

}

}
Composite

  • defines behavior for components having children.
  • stores child components.
  • implements child-related operations in the Component interface.
class CompositeElement : DrawingElement

{

private ArrayList elements = new ArrayList();

// Constructor

public CompositeElement(string name) : base(name)

{

}

public override void Add(DrawingElement d)

{

elements.Add(d);

}

public override void Remove(DrawingElement d)

{

elements.Remove(d);

}

public override void Display(int indent)

{

Console.WriteLine(new String('-', indent) +

"+ " + name);

// Display each child element on this node

foreach (DrawingElement c in elements)

{

c.Display(indent + 2);

}

}

}
static void Main()

{

// Create a tree structure

CompositeElement root = new CompositeElement("Picture");

root.Add(new PrimitiveElement("Red Line"));

root.Add(new PrimitiveElement("Blue Circle"));

CompositeElement comp = new CompositeElement("Two Circles");

comp.Add(new PrimitiveElement("Black Circle"));

comp.Add(new PrimitiveElement("White Circle"));

root.Add(comp);

// Add and remove a PrimitiveElement

PrimitiveElement pe = new PrimitiveElement("Yellow Line");

root.Add(pe);

root.Remove(pe);

// Recursively display nodes

root.Display(1);

}

Decorator
Add responsibilities to objects dynamically
Definition
Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

Usage
Medium

Participants
Component

  • defines the interface for objects that can have responsibilities added to them dynamically.
abstract class LibraryItem

{

private int numCopies;

// Property

public int NumCopies

{

get{ return numCopies; }

set{ numCopies = value; }

}

public abstract void Display();

}

ConcreteComponent

  • defines an object to which additional responsibilities can be attached.
1.

class Book : LibraryItem

{

private string author;

private string title;

// Constructor

public Book(string author,string title,int numCopies)

{

this.author = author;

this.title = title;

this.NumCopies = numCopies;

}

public override void Display()

{

Console.WriteLine("\nBook ------ ");

Console.WriteLine(" Author: {0}", author);

Console.WriteLine(" Title: {0}", title);

Console.WriteLine(" # Copies: {0}", NumCopies);

}

}

2.
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;

this.NumCopies = numCopies;

this.playTime = playTime;

}

public override void Display()

{

Console.WriteLine("\nVideo ----- ");

Console.WriteLine(" Director: {0}", director);

Console.WriteLine(" Title: {0}", title);

Console.WriteLine(" # Copies: {0}", NumCopies);

Console.WriteLine(" Playtime: {0}\n", playTime);

}

}
Decorator

  • maintains a reference to a Component object and defines an interface that conforms to Component's interface.
abstract class Decorator : LibraryItem

{

protected LibraryItem libraryItem;

// Constructor

public Decorator(LibraryItem libraryItem)

{

this.libraryItem = libraryItem;

}

public override void Display()

{

libraryItem.Display();

}

}

ConcreteDecorator

  • adds responsibilities to the component.
class Borrowable : Decorator

{

protected ArrayList borrowers = new ArrayList();

// Constructor

public Borrowable(LibraryItem libraryItem) : base(libraryItem)

{

}

public void BorrowItem(string name)

{

borrowers.Add(name);

libraryItem.NumCopies--;

}

public void ReturnItem(string name)

{

borrowers.Remove(name);

libraryItem.NumCopies++;

}

public override void Display()

{

base.Display();

foreach (string borrower in borrowers)

{

Console.WriteLine(" borrower: " + borrower);

}

}

}

static void Main()

{

Book book = new Book ("Worley", "Inside ASP.NET", 10);

book.Display();

Video video = new Video ("Spielberg", "Jaws", 23, 92);

video.Display();

// Make video borrowable, then borrow and display

Borrowable borrowvideo = new Borrowable(video);

borrowvideo.BorrowItem("Customer #1");

borrowvideo.BorrowItem("Customer #2");

borrowvideo.Display();

}

Façade
A single class that represents an entire subsystem
Definition
Provide a unified interface to a set of interfaces in a subsystem. Façade defines a higher-level interface that makes the subsystem easier to use.

Usage
High

Participants
Subsystem

  • implement subsystem functionality.
  • handle work assigned by the Facade object.
  • have no knowledge of the facade and keep no reference to it.
1.

class Bank

{

public bool HasSufficientSavings(Customer c, int amount)

{

Console.WriteLine("Check bank for " + c.Name);

return true;

}

}

2.

class Loan

{

public bool HasNoBadLoans(Customer c)

{

Console.WriteLine("Check loans for " + c.Name);

return true;

}

}

3.

class Customer

{

private string name;

public Customer(string name)

{

this.name = name;

}

public string Name

{

get{ return name; }

}

}
Facade

  • knows which subsystem classes are responsible for a request.
  • delegates client requests to appropriate subsystem objects.
class Mortgage

{

private Bank bank = new Bank();

private Loan loan = new Loan();

public bool IsEligible(Customer cust, int amount)

{

Console.WriteLine("{0} applies for {1:C} loan\n",cust.Name, amount);

bool eligible = true;

// Check creditworthyness of applicant

if (!bank.HasSufficientSavings(cust, amount))

{

eligible = false;

}

else if (!loan.HasNoBadLoans(cust))

{

eligible = false;

}

return eligible;

}

}
static void Main()

{

Mortgage mortgage = new Mortgage();

// Evaluate mortgage eligibility for customer

Customer customer = new Customer("Ann McKinsey");

bool eligable = mortgage.IsEligible(customer,125000);

Console.WriteLine("\n" + customer.Name + " has been " + (eligable ? "Approved" : "Rejected"));

}

Flyweight
A friend-grained instance used for efficient sharing
Definition
Use sharing to support large numbers of fine-grained objects efficiently.

Usage
Low

Participants
FlyweightFactory

  • creates and manages flyweight objects
  • ensures that flyweight are shared properly. When a client requests a flyweight, the FlyweightFactory objects supplies an existing instance or creates one, if none exists.
class CharacterFactory

{

private Hashtable characters = new Hashtable();

public Character GetCharacter(char key)

{

Character character = characters[key] as Character;

if (character == null)

{

switch (key)

{

case 'A': character = new CharacterA(); break;

case 'B': character = new CharacterB(); break;

//...

case 'Z': character = new CharacterZ(); break;

}

characters.Add(key, character);

}

return character;

}

}
Flyweight

  • declares an interface through which flyweights can receive and act on extrinsic state.
abstract class Character

{

protected char symbol;

protected int width;

protected int height;

protected int pointSize;

public abstract void Display(int pointSize);

}
ConcreteFlyweight

  • implements the Flyweight interface and adds storage for intrinsic state, if any.
  • A ConcreteFlyweight object must be sharable. Any state it stores must be intrinsic, that is, it must be independent of the ConcreteFlyweight object's context.
1.

class CharacterA : Character

{

// Constructor

public CharacterA()

{

this.symbol = 'A';

this.height = 100;

this.width = 120;

}

public override void Display(int pointSize)

{

this.pointSize = pointSize;

Console.WriteLine(this.symbol + " (pointsize " + this.pointSize + ")");

}

}

2.


class CharacterB : Character

{

// Constructor

public CharacterB()

{

this.symbol = 'B';

this.height = 100;

this.width = 140;

}

public override void Display(int pointSize)

{

this.pointSize = pointSize;

Console.WriteLine(this.symbol + " (pointsize " + this.pointSize + ")");

}

}

static void Main()

{

// Build a document with text

string document = "AABBAB";

char[] chars = document.ToCharArray();

CharacterFactory f = new CharacterFactory();

int pointSize = 10;

// For each character use a flyweight object

foreach (char c in chars)

{

pointSize++;

Character character = f.GetCharacter(c);

character.Display(pointSize);

}

}

Proxy
An object representing another object
Definition
Provide a surrogate or placeholder for another object to control access to it.

Usage
Medium High

Participants
Subject

  • defines the common interface for RealSubject and Proxy so that a Proxy can be used anywhere a RealSubject is expected.
public interface IMath

{

double Add(double x, double y);

double Sub(double x, double y);

}
RealSubject

  • defines the real object that the proxy represents.
class Math : IMath

{

public double Add(double x, double y){return x + y;}

public double Sub(double x, double y){return x - y;}

}

Proxy

  • maintains a reference that lets the proxy access the real subject. Proxy may refer to a Subject if the RealSubject and Subject interfaces are the same.
  • provides an interface identical to Subject's so that a proxy can be substituted for for the real subject.
  • controls access to the real subject and may be responsible for creating and deleting it.
  • other responsibilites depend on the kind of proxy:
  • remote proxies are responsible for encoding a request and its arguments and for sending the encoded request to the real subject in a different address space.
  • virtual proxies may cache additional information about the real subject so that they can postpone accessing it. For example, the ImageProxy from the Motivation caches the real images's extent.
  • protection proxies check that the caller has the access permissions required to perform a request.
class MathProxy : IMath

{

Math math;

public MathProxy()

{

math = new Math();

}

public double Add(double x, double y)

{

return math.Add(x,y);

}

public double Sub(double x, double y)

{

return math.Sub(x,y);

}

}
static void Main()

{

// Create math proxy

MathProxy p = new MathProxy();

// Do the math

Console.WriteLine("4 + 2 = " + p.Add(4, 2));

Console.WriteLine("4 - 2 = " + p.Sub(4, 2));

}

Behavioral patterns


Chain Of Responsibility
A way passing a request between a chain of objects
Definition
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.

Usage
Medium Low

Participants
Handler

  • defines an interface for handling the requests
  • (optional) implements the successor link
abstract class Approver

{

protected Approver successor;

public void SetSuccessor(Approver successor)

{

this.successor = successor;

}

public abstract void ProcessRequest(Purchase purchase);

}
ConcreteHandler

  • handles requests it is responsible for
  • can access its successor
  • if the ConcreteHandler can handle the request, it does so; otherwise it forwards the request to its successor
1.
class Director : Approver

{

public override void ProcessRequest(Purchase purchase)

{

if (purchase.Amount < 10000.0)

{

Console.WriteLine("{0} approved request# {1}", this.GetType().Name, purchase.Number);

}

else if (successor != null)

{

successor.ProcessRequest(purchase);

}

}

}

2.

class VicePresident : Approver

{

public override void ProcessRequest(Purchase purchase)

{

if (purchase.Amount < 25000.0)

{

Console.WriteLine("{0} approved request# {1}", this.GetType().Name, purchase.Number);

}

else if (successor != null)

{

successor.ProcessRequest(purchase);

}

}

}

3.
class President : Approver

{

public override void ProcessRequest(Purchase purchase)

{

if (purchase.Amount < 100000.0)

{

Console.WriteLine("{0} approved request# {1}", this.GetType().Name, purchase.Number);

}

else

{

Console.WriteLine("Request# {0} requires an executive meeting!", purchase.Number);

}

}

}

Responsibility Details
class Purchase

{

public int number;

public double amount;

public string purpose;

// Constructor

public Purchase(int number, double amount, string purpose)

{

this.number = number;

this.amount = amount;

this.purpose = purpose;

}

}



static void Main()

{

// Setup Chain of Responsibility

Director Larry = new Director();

VicePresident Sam = new VicePresident();

President Tammy = new President();

Larry.SetSuccessor(Sam);

Sam.SetSuccessor(Tammy);

Purchase p = new Purchase(2034, 350.00, "Supplies");

Larry.ProcessRequest(p);

p = new Purchase(2035, 32590.10, "Project X");

Larry.ProcessRequest(p);

}

Command
Encapsulate a command request as an object
Definition
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

Usage
Medium High

Participants
Command

  • declares an interface for executing an operation
abstract class Command

{

public abstract void Execute();

public abstract void UnExecute();

}
ConcreteCommand

  • defines a binding between a Receiver object and an action
  • implements Execute by invoking the corresponding operation(s) on Receiver
class CalculatorCommand : Command

{

char @operator;

int operand;

Calculator calculator;

public CalculatorCommand(Calculator calculator, char @operator, int operand)

{

this.calculator = calculator;

this.@operator = @operator;

this.operand = operand;

}

public char Operator

{

set{ @operator = value; }

}

public int Operand

{

set{ operand = value; }

}

public override void Execute()

{

calculator.Operation(@operator, operand);

}

public override void UnExecute()

{

calculator.Operation(Undo(@operator), operand);

}

private char Undo(char @operator)

{

char undo;

switch(@operator)

{

case '+': undo = '-'; break;

case '-': undo = '+'; break;

case '*': undo = '/'; break;

case '/': undo = '*'; break;

default : undo = ' '; break;

}

return undo;

}

}
Receiver

  • knows how to perform the operations associated with carrying out the request.
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;

}

Console.WriteLine("Current value = {0,3} (following {1} {2})", curr, @operator, operand);

}

}
Invoker

  • asks the command to carry out the request
class User

{

private Calculator calculator = new Calculator();

private ArrayList commands = new ArrayList();

private int current = 0;

public void Undo(int levels)

{

for (int i = 0; i < levels; i++)

{

if (current > 0)

{

Command command = commands[--current] as Command;

command.UnExecute();

}

}

}

public void Compute(char @operator, int operand)

{

Command command = new CalculatorCommand(calculator, @operator, operand);

command.Execute();

commands.Add(command);

current++;

}

}
static void Main()

{

User user = new User();

user.Compute('+', 100);

user.Compute('-', 50);

user.Compute('*', 10);

user.Compute('/', 2);

// Undo 4 commands

user.Undo(2);

}

Interpreter
A way to include language elements in a program
Definition
Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.

Usage
Low

Participants
Context

  • contains information that is global to the interpreter
class Context

{

private string input;

private int output;

public Context(string input)

{

this.input = input;

}

}




AbstractExpression


  • declares an interface for executing an operation
abstract class Expression

{

public void Interpret(Context context)

{

if (context.Input.Length == 0)

return;

if (context.Input.StartsWith(Nine()))

{

context.Output += (9 * Multiplier());

context.Input = context.Input.Substring(2);

}

else if (context.Input.StartsWith(Four()))

{

context.Output += (4 * Multiplier());

context.Input = context.Input.Substring(2);

}

else if (context.Input.StartsWith(Five()))

{

context.Output += (5 * Multiplier());

context.Input = context.Input.Substring(1);

}

while (context.Input.StartsWith(One()))

{

context.Output += (1 * Multiplier());

context.Input = context.Input.Substring(1);

}

}

public abstract string One();

public abstract string Four();

public abstract string Five();

public abstract string Nine();

public abstract int Multiplier();

}

TerminalExpression


  • implements an Interpret operation associated with terminal symbols in the grammar.
  • an instance is required for every terminal symbol in the sentence.
1.

class ThousandExpression : Expression

{

public override string One() { return "M"; }

public override string Four(){ return " "; }

public override string Five(){ return " "; }

public override string Nine(){ return " "; }

public override int Multiplier() { return 1000; }

}

2.

class HundredExpression : Expression

{

public override string One() { return "C"; }

public override string Four(){ return "CD"; }

public override string Five(){ return "D"; }

public override string Nine(){ return "CM"; }

public override int Multiplier() { return 100; }

}

3.

class TenExpression : Expression

{

public override string One() { return "X"; }

public override string Four(){ return "XL"; }

public override string Five(){ return "L"; }

public override string Nine(){ return "XC"; }

public override int Multiplier() { return 10; }

}

4.

class OneExpression : Expression

{

public override string One() { return "I"; }

public override string Four(){ return "IV"; }

public override string Five(){ return "V"; }

public override string Nine(){ return "IX"; }

public override int Multiplier() { return 1; }

}
static void Main()

{

string roman = "MCMXXVIII";

Context context = new Context(roman);

ArrayList tree = new ArrayList();

tree.Add(new ThousandExpression());

tree.Add(new HundredExpression());

tree.Add(new TenExpression());

tree.Add(new OneExpression());

foreach (Expression exp in tree)

{

exp.Interpret(context);

}

Console.WriteLine("{0} = {1}", roman, context.Output);

}

Iterator
Sequentially access the elements of a collection
Definition
Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

Usage
High

Participants
Aggregate

  • defines an interface for creating an Iterator object
interface IAbstractCollection

{

Iterator CreateIterator();

}
ConcreteAggregate

  • implements the Iterator creation interface to return an instance of the proper ConcreteIterator
class Collection : IAbstractCollection

{

private ArrayList items = new ArrayList();

public Iterator CreateIterator()

{

return new Iterator(this);

}

// Property

public int Count

{

get{ return items.Count; }

}

// Indexer

public object this[int index]

{

get{ return items[index]; }

set{ items.Add(value); }

}

}
Iterator

  • defines an interface for accessing and traversing elements.
interface IAbstractIterator

{

Item First();

Item Next();

bool IsDone{ get; }

Item CurrentItem{ get; }

}
ConcreteIterator

  • implements the Iterator interface.
  • keeps track of the current position in the traversal of the aggregate.
class Iterator : IAbstractIterator

{

private Collection collection;

private int current = 0;

private int step = 1;

public Iterator(Collection collection)

{

this.collection = collection;

}

public Item First()

{

current = 0;

return collection[current] as Item;

}

public Item Next()

{

current += step;

if (!IsDone)

return collection[current] as Item;

else

return null;

}

public int Step

{

get{ return step; }

set{ step = value; }

}

public Item CurrentItem

{

get

{

return collection[current] as Item;

}

}

public bool IsDone

{

get

{

return current >= collection.Count ? true : false;

}

}

}
static void Main()

{

// Build a collection

Collection collection = new Collection();

collection[0] = new Item("Item 0");

collection[1] = new Item("Item 1");

collection[2] = new Item("Item 2");

Iterator iterator = new Iterator(collection);

iterator.Step = 2;

for(Item item = iterator.First();

!iterator.IsDone; item = iterator.Next())

{

Console.WriteLine(item.Name);

}

}

Mediator
Defines simplified communication between classes
Definition
Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.

Usage
Medium Low

Participants
Mediator

  • defines an interface for communicating with Colleague objects
abstract class AbstractChatroom

{

public abstract void Register(Participant participant);

public abstract void Send(

string from, string to, string message);

}
ConcreteMediator

  • implements cooperative behavior by coordinating Colleague objects
  • knows and maintains its colleagues
class Chatroom : AbstractChatroom

{

private Hashtable participants = new Hashtable();

public override void Register(Participant participant)

{

if (participants[participant.Name] == null)

{

participants[participant.Name] = participant;

}

participant.Chatroom = this;

}

public override void Send(string from, string to, string message)

{

Participant pto = (Participant)participants[to];

if (pto != null)

{

pto.Receive(from, message);

}

}

}
Colleague

  • each Colleague class knows its Mediator object
  • each colleague communicates with its mediator whenever it would have otherwise communicated with another colleague
class Participant

{

private Chatroom chatroom;

private string name;

public Participant(string name)

{ this.name = name; }

public string Name

{ get{ return name; }

}

public Chatroom Chatroom

{

set{ chatroom = value; }

get{ return chatroom; }

}

public void Send(string to, string message)

{

chatroom.Send(name, to, message);

}

public virtual void Receive(string from, string message)

{

Console.WriteLine("{0} to {1}: '{2}'", from, Name, message);

}

}
static void Main()

{

Chatroom chatroom = new Chatroom();

Participant George = new Participant("George");

Participant John= new Participant("John");

chatroom.Register(George);

chatroom.Register(John);

George.Send ("John", "Hi John!");

John.Send("George", "My sweet Lord");

George.Send ("John", "Can't buy me love");

}

Memento
Capture and restore an object's internal state
Definition
Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later.

Usage
Low

Participants
Originator

  • creates a memento containing a snapshot of its current internal state.
  • uses the memento to restore its internal state
class SalesProspect

{

private string name;

private string phone;

private double budget;

public string Name

{

get{ return name; }

set

{

name = value;

Console.WriteLine("Name: " + name);

}

}

public string Phone

{

get{ return phone; }

set

{

phone = value;

Console.WriteLine("Phone: " + phone);

}

}

public double Budget

{

get{ return budget; }

set

{

budget = value;

Console.WriteLine("Budget: " + budget);

}

}

public Memento SaveMemento()

{

Console.WriteLine("\nSaving state --\n");

return new Memento(name, phone, budget);

}

public void RestoreMemento(Memento memento)

{

Console.WriteLine("\nRestoring state --\n");

this.Name = memento.Name;

this.Phone = memento.Phone;

this.Budget = memento.Budget;

}

}
Memento

  • stores internal state of the Originator object. The memento may store as much or as little of the originator's internal state as necessary at its originator's discretion.
  • protect against access by objects of other than the originator. Mementos have effectively two interfaces. Caretaker sees a narrow interface to the Memento -- it can only pass the memento to the other objects. Originator, in contrast, sees a wide interface, one that lets it access all the data necessary to restore itself to its previous state. Ideally, only the originator that produces the memento would be permitted to access the memento's internal state.
class Memento

{

private string name;

private string phone;

private double budget;

public Memento(string name, string phone, double budget)

{

this.name = name;

this.phone = phone;

this.budget = budget;

}

public string Name

{

get{ return name; }

set{ name = value; }

}

public string Phone

{

get{ return phone; }

set{ phone = value; }

}

public double Budget

{

get{ return budget; }

set{ budget = value; }

}

}
Caretaker

  • is responsible for the memento's safekeeping
  • never operates on or examines the contents of a memento.
class ProspectMemory

{

private Memento memento;

public Memento Memento

{

set{ memento = value; }

get{ return memento; }

}

}
static void Main()

{

SalesProspect s = new SalesProspect();

s.Name = "Noel van Halen";

s.Phone = "(412) 256-0990";

s.Budget = 25000.0;

// Store internal state

ProspectMemory m = new ProspectMemory();

m.Memento = s.SaveMemento();

// Continue changing originator

s.Name = "Leo Welch";

s.Phone = "(310) 209-7111";

s.Budget = 1000000.0;

// Restore saved state

s.RestoreMemento(m.Memento);

}

Observer
A way of notifying change to a number of classes
Definition
Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

Usage
High

Participants
Subject

  • knows its observers. Any number of Observer objects may observe a subject
  • provides an interface for attaching and detaching Observer objects.
abstract class Stock

{

protected string symbol;

protected double price;

private ArrayList investors = new ArrayList();

public Stock(string symbol, double price)

{

this.symbol = symbol;

this.price = price;

}

public void Attach(Investor investor)

{

investors.Add(investor);

}

public void Notify()

{

foreach (Investor investor in investors)

{

investor.Update(this);

}

Console.WriteLine("");

}

public double Price

{

get{ return price; }

set

{

price = value;

Notify();

}

}

public string Symbol

{

get{ return symbol; }

set{ symbol = value; }

}

}
ConcreteSubject

  • stores state of interest to ConcreteObserver
  • sends a notification to its observers when its state changes
class IBM : Stock

{

// Constructor

public IBM(string symbol, double price)

: base(symbol, price)

{

}

}
Observer

  • defines an updating interface for objects that should be notified of changes in a subject.
interface IInvestor

{

void Update(Stock stock);

}
ConcreteObserver

  • maintains a reference to a ConcreteSubject object
  • stores state that should stay consistent with the subject's
  • implements the Observer updating interface to keep its state consistent with the subject's
class Investor : IInvestor

{

private string name;

private Stock stock;

public Investor(string name)

{

this.name = name;

}

public void Update(Stock stock)

{

Console.WriteLine("Notified {0} of {1}'s change to {2:C}", name, stock.Symbol, stock.Price);

}

public Stock Stock

{

get{ return stock; }

set{ stock = value; }

}

}
static void Main()

{

// Create investors

Investor s = new Investor("Sorros");

Investor b = new Investor("Berkshire");

// Create IBM stock and attach investors

IBM ibm = new IBM("IBM", 120.00);

ibm.Attach(s);

ibm.Attach(b);

ibm.Price = 120.10;

ibm.Price = 121.00;

}

State
Alter an object's behavior when its state changes.
Definition
Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.

Usage
Medium

Participants
State

  • defines an interface for encapsulating the behavior associated with a particular state of the Context.
abstract class State

{

public Account account;

public double balance;

protected double interest;

protected double lowerLimit;

protected double upperLimit;

public abstract void Deposit(double amount);

public abstract void Withdraw(double amount);

}
ConcreteState

  • stores state of interest to ConcreteObserver
  • sends a notification to its observers when its state changes
1.
class SilverState : State

{

public SilverState(State state) : this( state.Balance, state.Account)

{ }

public SilverState(double balance, Account account)

{

this.balance = balance;

this.account = account;

Initialize();

}

private void Initialize()

{

interest = 0.0;

lowerLimit = 0.0;

upperLimit = 1000.0;

}

public override void Deposit(double amount)

{

balance += amount;

StateChangeCheck();

}

public override void Withdraw(double amount)

{

balance -= amount;

StateChangeCheck();

}

private void StateChangeCheck()

{

if (balance > upperLimit)

{

account.State = new GoldState(this);

}

}

}

2.

class GoldState : State

{

// Overloaded constructors

public GoldState(State state) : this(state.Balance,state.Account)

{

}

public GoldState(double balance, Account account)

{

this.balance = balance;

this.account = account;

Initialize();

}

private void Initialize()

{

interest = 0.05;

lowerLimit = 1000.0;

upperLimit = 10000000.0;

}

public override void Deposit(double amount)

{

balance += amount;

StateChangeCheck();

}

public override void Withdraw(double amount)

{

balance -= amount;

StateChangeCheck();

}

private void StateChangeCheck()

{

if (balance < lowerLimit)

{

account.State = new SilverState(this);

}

}

}
Context

  • defines the interface of interest to clients
  • maintains an instance of a ConcreteState subclass that defines the current state.
class Account

{

private State state;

private string owner;

public Account(string owner)

{

// New accounts are 'Silver' by default

this.owner = owner;

state = new SilverState(0.0, this);

}

public double Balance

{

get{ return state.Balance; }

}

public State State

{

get{ return state; }

set{ state = value; }

}

public void Deposit(double amount)

{

state.Deposit(amount);

Console.WriteLine(" Balance = {0:C}", this.Balance);

}

public void Withdraw(double amount)

{

state.Withdraw(amount);

Console.WriteLine(" Balance = {0:C}", this.Balance);

}

}
static void Main()

{

// Open a new account

Account account = new Account("Jim Johnson");

account.Deposit(500.0);

account.Deposit(300.0);

account.Withdraw(1100.00);

}




Strategy
Encapsulates an algorithm inside a class
Definition
Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

Usage
Medium High

Participants
Strategy

  • declares an interface common to all supported algorithms. Context uses this interface to call the algorithm defined by a ConcreteStrategy
abstract class SortStrategy

{

public abstract void Sort(ArrayList list);

}
ConcreteStrategy

  • implements the algorithm using the Strategy interface
1.
class QuickSort : SortStrategy

{

public override void Sort(ArrayList list)

{

list.Sort(); // Default is Quicksort

Console.WriteLine("QuickSorted list ");

}

}

2.
class ShellSort : SortStrategy

{

public override void Sort(ArrayList list)

{

Console.WriteLine("ShellSorted list ");

}

}
Context

  • is configured with a ConcreteStrategy object
  • maintains a reference to a Strategy object
  • may define an interface that lets Strategy access its data.
class SortedList

{

private ArrayList list = new ArrayList();

private SortStrategy sortstrategy;

public void SetSortStrategy(SortStrategy sortstrategy)

{

this.sortstrategy = sortstrategy;

}

public void Add(string name)

{

list.Add(name);

}

public void Sort()

{

sortstrategy.Sort(list);

foreach (string name in list)

{

Console.WriteLine(" " + name);

}

}

}
static void Main()

{

SortedList studentRecords = new SortedList();

studentRecords.Add("Samual");

studentRecords.Add("Jimmy");

studentRecords.Add("Sandra");

studentRecords.SetSortStrategy(new QuickSort());

studentRecords.Sort();

studentRecords.SetSortStrategy(new MergeSort());

studentRecords.Sort();

}

Template
Defer the exact steps of an algorithm inside a class
Definition
Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.

Usage
Medium

Participants
AbstractClass

  • defines abstract primitive operations that concrete subclasses define to implement steps of an algorithm
  • implements a template method defining the skeleton of an algorithm. The template method calls primitive operations as well as operations defined in AbstractClass or those of other objects.
abstract class DataAccessObject

{

protected string connectionString;

protected DataSet dataSet;

public virtual void Connect()

{

connectionString = "provider=Microsoft.JET.OLEDB.4.0;data source=.. ..";

}

public abstract void Select();

public abstract void Process();

public virtual void Disconnect()

{ connectionString = ""; }

public void Run()

{

Connect();

Select();

Process();

Disconnect();

}

}
ConcreteClass

  • implements the primitive operations ot carry out subclass-specific steps of the algorithm
1.

class Categories : DataAccessObject

{

public override void Select()

{

string sql = "select CategoryName from Categories";

OleDbDataAdapter dataAdapter = new OleDbDataAdapter(sql, connectionString);

dataSet = new DataSet();

dataAdapter.Fill(dataSet, "Categories");

}

public override void Process()

{

DataTable dataTable = dataSet.Tables["Categories"];

foreach (DataRow row in dataTable.Rows)

{

Console.WriteLine(row["CategoryName"]);

}

}

}

2.

class Products : DataAccessObject

{

public override void Select()

{

string sql = "select ProductName from Products";

OleDbDataAdapter dataAdapter = new OleDbDataAdapter(sql, connectionString);

dataSet = new DataSet();

dataAdapter.Fill(dataSet, "Products");

}

public override void Process()

{

DataTable dataTable = dataSet.Tables["Products"];

foreach (DataRow row in dataTable.Rows)

{

Console.WriteLine(row["ProductName"]);

}

Console.WriteLine();

}

}
static void Main()

{

DataAccessObject dao;

dao = new Categories();

dao.Run();

dao = new Products();

dao.Run();

}

Visitor
Defines a new operation to a class without change
Definition
Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

Usage
Low

Participants
Visitor

  • declares a Visit operation for each class of ConcreteElement in the object structure. The operation's name and signature identifies the class that sends the Visit request to the visitor. That lets the visitor determine the concrete class of the element being visited. Then the visitor can access the elements directly through its particular interface
interface IVisitor

{

void Visit(Element element);

}
ConcreteVisitor

  • implements each operation declared by Visitor. Each operation implements a fragment of the algorithm defined for the corresponding class or object in the structure. ConcreteVisitor provides the context for the algorithm and stores its local state. This state often accumulates results during the traversal of the structure.
1.

class IncomeVisitor : IVisitor

{

public void Visit(Element element)

{

Employee employee = element as Employee;

employee.Income *= 1.10;

Console.WriteLine("{0}{1}'s new income: {2:C}", employee.GetType().Name, employee.Name, employee.Income);

}

}

2.

class VacationVisitor : IVisitor

{

public void Visit(Element element)

{

Employee employee = element as Employee;

Console.WriteLine("{0}{1}'s new vacation days:{2}", employee.GetType().Name, employee.Name, employee.VacationDays);

}

}
Element

  • defines an Accept operation that takes a visitor as an argument.
abstract class Element

{

public abstract void Accept(IVisitor visitor);

}
ConcreteElement

  • implements an Accept operation that takes a visitor as an argument
class Employee : Element

{

string name;

double income;

int vacationDays;

public Employee(string name, double income, int vacationDays)

{

this.name = name;

this.income = income;

this.vacationDays = vacationDays;

}

public string Name

{

get{ return name; }

set{ name = value; }

}

public double Income

{

get{ return income; }

set{ income = value; }

}

public int VacationDays

{

get{ return vacationDays; }

set{ vacationDays = value; }

}

public override void Accept(IVisitor visitor)

{

visitor.Visit(this);

}

}
class Clerk : Employee

{

public Clerk() : base("Hank", 25000.0, 14)

{

}

}

class Director : Employee

{

public Director() : base("Elly", 35000.0, 16)

{

}

}
ObjectStructure

  • can enumerate its elements
  • may provide a high-level interface to allow the visitor to visit its elements
  • may either be a Composite (pattern) or a collection such as a list or a set
class Employees

{

private ArrayList employees = new ArrayList();

public void Attach(Employee employee)

{

employees.Add(employee);

}

public void Detach(Employee employee)

{

employees.Remove(employee);

}

public void Accept(IVisitor visitor)

{

foreach (Employee e in employees)

{

e.Accept(visitor);

}

Console.WriteLine();

}

}
static void Main()

{

// Setup employee collection

Employees e = new Employees();

e.Attach(new Clerk());

e.Attach(new Director());

e.Accept(new IncomeVisitor());

e.Accept(new VacationVisitor());

}