GoF Design Patterns
GoF Design Patterns
Creational Patterns
Abstract
Creates an instance of several families of classes
Factory
Builder Separates object construction from its representation
Factory
Creates an instance of several derived classes
Method
Prototype A fully initialized instance to be copied or cloned
Singleton A class of which only a single instance can exist
Structural Patterns
Adapter Match interfaces of different classes
Bridge Separates an object’s interface from its implementation
Composite A tree structure of simple and composite objects
Decorator Add responsibilities to objects dynamically
Facade A single class that represents an entire subsystem
Flyweight A fine-grained instance used for efficient sharing
Proxy An object representing another object
Behavioral Patterns
Chain of Resp. A way of passing a request between a chain of objects
Command Encapsulate a command request as an object
Interpreter A way to include language elements in a program
Iterator Sequentially access the elements of a collection
Mediator Defines simplified communication between classes
Memento Capture and restore an object's internal state
Observer A way of notifying change to a number of classes
State Alter an object's behavior when its state changes
Strategy Encapsulates an algorithm inside a class
Template
Defer the exact steps of an algorithm to a subclass
Method
Visitor Defines a new operation to a class without change
definition
participants
• 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
return to top
sample code in C#
using System;
namespace DoFactory.GangOfFour.Abstract.Structural
{
// MainApp test application
class MainApp
{
public static void Main()
{
// Abstract factory #1
AbstractFactory factory1 = new ConcreteFactory1();
Client c1 = new Client(factory1);
c1.Run();
// Abstract factory #2
AbstractFactory factory2 = new ConcreteFactory2();
Client c2 = new Client(factory2);
c2.Run();
// "AbstractFactory"
// "ConcreteFactory2"
// "AbstractProductA"
// "AbstractProductB"
// "ProductA1"
class ProductA1 : AbstractProductA
{
}
// "ProductB1"
// "ProductA2"
// "ProductB2"
class Client
{
private AbstractProductA AbstractProductA;
private AbstractProductB AbstractProductB;
// Constructor
public Client(AbstractFactory factory)
{
AbstractProductB = factory.CreateProductB();
AbstractProductA = factory.CreateProductA();
}
Output
ProductB1 interacts with ProductA1
ProductB2 interacts with ProductA2
using System;
namespace DoFactory.GangOfFour.Abstract.RealWorld
{
// MainApp test application
class MainApp
{
public static void Main()
{
// Create and run the Africa animal world
ContinentFactory africa = new AfricaFactory();
AnimalWorld world = new AnimalWorld(africa);
world.RunFoodChain();
// "AbstractFactory"
// "ConcreteFactory1"
// "ConcreteFactory2"
// "AbstractProductB"
// "ProductA1"
// "ProductB1"
// "ProductA2"
// "ProductB2"
// "Client"
class AnimalWorld
{
private Herbivore herbivore;
private Carnivore carnivore;
// Constructor
public AnimalWorld(ContinentFactory factory)
{
carnivore = factory.CreateCarnivore();
herbivore = factory.CreateHerbivore();
}
Output
Lion eats Wildebeest
Wolf eats Bison
Hide code
definition
return to top
participants
• Builder (VehicleBuilder)
o specifies an abstract interface for creating parts of a Product object
• ConcreteBuilder (MotorCycleBuilder, CarBuilder, ScooterBuilder)
o constructs and assembles parts of the product by implementing the
Builder interface
o defines and keeps track of the representation it creates
o provides an interface for retrieving the product
• Director (Shop)
o constructs an object using the Builder interface
• Product (Vehicle)
o represents the complex object under construction. ConcreteBuilder
builds the product's internal representation and defines the process
by which it's assembled
o includes classes that define the constituent parts, including interfaces
for assembling the parts into the final result
return to top
sample code in C#
namespace DoFactory.GangOfFour.Builder.Structural
{
// MainApp test application
director.Construct(b2);
Product p2 = b2.GetResult();
p2.Show();
// "Director"
class Director
{
// Builder uses a complex series of steps
public void Construct(Builder builder)
{
builder.BuildPartA();
builder.BuildPartB();
}
}
// "Builder"
// "ConcreteBuilder1"
// "ConcreteBuilder2"
// "Product"
class Product
{
ArrayList parts = new ArrayList();
Output
Product Parts -------
PartA
PartB
This real-world code demonstates the Builder pattern in which different vehicles are assembled in
a step-by-step fashion. The Shop uses VehicleBuilders to construct a variety of Vehicles in a
series of sequential steps.
Hide code
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Builder.RealWorld
{
// MainApp test application
shop.Construct(b2);
b2.Vehicle.Show();
shop.Construct(b3);
b3.Vehicle.Show();
// "Director"
class Shop
{
// Builder uses a complex series of steps
public void Construct(VehicleBuilder vehicleBuilder)
{
vehicleBuilder.BuildFrame();
vehicleBuilder.BuildEngine();
vehicleBuilder.BuildWheels();
vehicleBuilder.BuildDoors();
}
}
// "Builder"
// Property
public Vehicle Vehicle
{
get{ return vehicle; }
}
// "ConcreteBuilder1"
// "ConcreteBuilder2"
// "ConcreteBuilder3"
// "Product"
class Vehicle
{
private string type;
private Hashtable parts = new Hashtable();
// Constructor
public Vehicle(string type)
{
this.type = type;
}
Output
---------------------------
Vehicle Type: Scooter
Frame : Scooter Frame
Engine : none
#Wheels: 2
#Doors : 0
---------------------------
Vehicle Type: Car
Frame : Car Frame
Engine : 2500 cc
#Wheels: 4
#Doors : 4
---------------------------
Vehicle Type: MotorCycle
Frame : MotorCycle Frame
Engine : 500 cc
#Wheels: 2
#Doors : 0
Hide code
return to top
participants
• Product (Page)
o defines the interface of objects the factory method creates
• ConcreteProduct (SkillsPage, EducationPage, ExperiencePage)
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.
return to top
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.
Hide code
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Factory.Structural
{
class MainApp
{
static void Main()
{
// An array of creators
Creator[] creators = new Creator[2];
creators[0] = new ConcreteCreatorA();
creators[1] = new ConcreteCreatorB();
// "Product"
// "ConcreteProductB"
// "Creator"
// "ConcreteCreator"
// "ConcreteCreator"
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.
Hide code
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Factory.RealWorld
{
class MainApp
{
static void Main()
{
// Note: constructors call Factory Method
Document[] documents = new Document[2];
documents[0] = new Resume();
documents[1] = new Report();
// "Product"
// "ConcreteProduct"
// "ConcreteProduct"
// "ConcreteProduct"
// "ConcreteProduct"
// "ConcreteProduct"
// "ConcreteProduct"
// "ConcreteProduct"
// "ConcreteProduct"
// "Creator"
// Factory Method
public abstract void CreatePages();
}
// "ConcreteCreator"
// "ConcreteCreator"
class Report : Document
{
// Factory Method implementation
public override void CreatePages()
{
Pages.Add(new IntroductionPage());
Pages.Add(new ResultsPage());
Pages.Add(new ConclusionPage());
Pages.Add(new SummaryPage());
Pages.Add(new BibliographyPage());
}
}
}
Output
Resume -------
SkillsPage
EducationPage
ExperiencePage
Report -------
IntroductionPage
ResultsPage
ConclusionPage
SummaryPage
BibliographyPage
definition
Specify the kind of objects to create using a prototypical instance,
and create new objects by copying this prototype.
return to top
participants
• Prototype (ColorPrototype)
o declares an interace 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
return to top
sample code in C#
namespace DoFactory.GangOfFour.Prototype.Structural
{
class MainApp
{
// "Prototype"
// Constructor
public Prototype(string id)
{
this.id = id;
}
// Property
public string Id
{
get{ return id; }
}
// "ConcretePrototype1"
// "ConcretePrototype2"
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.
Hide code
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Prototype.RealWorld
{
class MainApp
{
static void Main()
{
ColorManager colormanager = new ColorManager();
Color color;
name = "peace";
color = colormanager[name].Clone() as Color;
name = "flame";
color = colormanager[name].Clone() as Color;
// "Prototype"
// "ConcretePrototype"
// Constructor
public Color(int red, int green, int blue)
{
this.red = red;
this.green = green;
this.blue = blue;
}
// Prototype manager
class ColorManager
{
Hashtable colors = new Hashtable();
// Indexer
public ColorPrototype this[string name]
{
get
{
return colors[name] as ColorPrototype;
}
set
{
colors.Add(name, value);
}
}
}
}
Output
Cloning color RGB: 255, 0, 0
Cloning color RGB: 128,211,128
Cloning color RGB: 211, 34, 20
definition
Ensure a class has only one instance and provide a global point of
access to it.
participants
• 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.
return to top
sample code in C#
using System;
namespace DoFactory.GangOfFour.Singleton.Structural
{
class MainApp
{
if (s1 == s2)
{
Console.WriteLine("Objects are the same instance");
}
// "Singleton"
class Singleton
{
private static Singleton instance;
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.
Hide code
using System;
using System.Collections;
using System.Threading;
namespace DoFactory.GangOfFour.Singleton.RealWorld
{
class MainApp
{
static void Main()
{
LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
LoadBalancer b4 = LoadBalancer.GetLoadBalancer();
// Same instance?
if (b1 == b2 && b2 == b3 && b3 == b4)
{
Console.WriteLine("Same instance\n");
}
// "Singleton"
class LoadBalancer
{
private static LoadBalancer instance;
private ArrayList servers = new ArrayList();
// Constructor (protected)
protected LoadBalancer()
{
// List of available servers
servers.Add("ServerI");
servers.Add("ServerII");
servers.Add("ServerIII");
servers.Add("ServerIV");
servers.Add("ServerV");
}
return instance;
}
Output
Same instance
ServerIII
ServerII
ServerI
ServerII
ServerI
ServerIII
ServerI
ServerIII
ServerIV
ServerII
ServerII
ServerIII
ServerIV
ServerII
ServerIV
Show code
return to top
return to top
Participants
• Target (ChemicalCompound)
o defines the domain-specific interface that Client uses.
• Adapter (Compound)
o adapts the interface Adaptee to the Target interface.
• Adaptee (ChemicalDatabank)
o defines an existing interface that needs adapting.
• Client (AdapterApp)
o collaborates with objects conforming to the Target interface.
return to top
Sample code in C#
This structural code demonstrates the Adapter pattern which maps the
interface of one class onto another so that they can work together.
These incompatible classes may come from different libraries or
frameworks.
Show code
This real-world code demonstrates the use of a legacy chemical databank. Chemical compound
objects access the databank through an Adapter interface.
Hide code
using System;
namespace DoFactory.GangOfFour.Adapter.RealWorld
{
class MainApp
{
static void Main()
{
// Non-adapted chemical compound
Compound stuff = new Compound("Unknown");
stuff.Display();
class Compound
{
protected string name;
protected float boilingPoint;
protected float meltingPoint;
protected double molecularWeight;
protected string molecularFormula;
// Constructor
public Compound(string name)
{
this.name = name;
}
// "Adapter"
// Constructor
public RichCompound(string name) : base(name)
{
}
// "Adaptee"
class ChemicalDatabank
{
// The Databank 'legacy API'
public float GetCriticalPoint(string compound, string point)
{
float temperature = 0.0F;
// Melting Point
if (point == "M")
{
switch (compound.ToLower())
{
case "water" : temperature = 0.0F; break;
case "benzene" : temperature = 5.5F; break;
case "alcohol" : temperature = -114.1F; break;
}
}
// Boiling Point
else
{
switch (compound.ToLower())
{
case "water" : temperature = 100.0F; break;
case "benzene" : temperature = 80.1F; break;
case "alcohol" : temperature = 78.3F; break;
}
}
return temperature;
}
Output
Compound: Unknown ------
Hide code
return to top
definition
return to top
participants
• Abstraction (BusinessObject)
o defines the abstraction's interface.
o maintains a reference to an object of type Implementor.
• RefinedAbstraction (CustomersBusinessObject)
o extends the interface defined by Abstraction.
• Implementor (DataObject)
o 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.
• ConcreteImplementor (CustomersDataObject)
o implements the Implementor interface and defines its concrete
implementation.
return to top
sample code in C#
This real-world code demonstrates the Bridge pattern in which a BusinessObject abstraction is
decoupled from the implementation in DataObject. The DataObject implementations can evolve
dynamically without changing any clients.
Hide code
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Bridge.RealWorld
{
class MainApp
{
static void Main()
{
// Create RefinedAbstraction
Customers customers =
new Customers("Chicago");
// Set ConcreteImplementor
customers.Data = new CustomersData();
customers.ShowAll();
// "Abstraction"
class CustomersBase
{
private DataObject dataObject;
protected string group;
// Property
public DataObject Data
{
set{ dataObject = value; }
get{ return dataObject; }
}
// "RefinedAbstraction"
// "Implementor"
// "ConcreteImplementor"
public CustomersData()
{
// Loaded from a database
customers.Add("Jim Jones");
customers.Add("Samual Jackson");
customers.Add("Allen Good");
customers.Add("Ann Stills");
customers.Add("Lisa Giolani");
}
Output
Jim Jones
Samual Jackson
Allen Good
------------------------
Customer Group: Chicago
Jim Jones
Samual Jackson
Allen Good
Ann Stills
Lisa Giolani
Henry Velasquez
------------------------
Hide code
definition
return to top
participants
• Component (DrawingElement)
o declares the interface for objects in the composition.
o implements default behavior for the interface common to all classes,
as appropriate.
o declares an interface for accessing and managing its child
components.
o (optional) defines an interface for accessing a component's parent in
the recursive structure, and implements it if that's appropriate.
• Leaf (PrimitiveElement)
o represents leaf objects in the composition. A leaf has no children.
o defines behavior for primitive objects in the composition.
• Composite (CompositeElement)
o defines behavior for components having children.
o stores child components.
o implements child-related operations in the Component interface.
• Client (CompositeApp)
o manipulates objects in the composition through the Component
interface.
return to top
sample code in C#
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Composite.Structural
{
class MainApp
{
static void Main()
{
// Create a tree structure
Composite root = new Composite("root");
root.Add(new Leaf("Leaf A"));
root.Add(new Leaf("Leaf B"));
root.Add(comp);
root.Add(new Leaf("Leaf C"));
// "Component"
// Constructor
public Component(string name)
{
this.name = name;
}
// "Composite"
// Constructor
public Composite(string name) : base(name)
{
}
// "Leaf"
Output
-root
---Leaf A
---Leaf B
---Composite X
-----Leaf XA
-----Leaf XB
---Leaf C
This real-world code demonstrates the Composite pattern used in building a graphical tree
structure made up of primitive nodes (lines, circles, etc) and composite nodes (groups of drawing
elements that make up more complex elements).
Hide code
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Composite.RealWorld
{
class MainApp
{
static void Main()
{
// Create a tree structure
CompositeElement root =
new CompositeElement("Picture");
root.Add(new PrimitiveElement("Red Line"));
root.Add(new PrimitiveElement("Blue Circle"));
root.Add(new PrimitiveElement("Green Box"));
CompositeElement comp =
new CompositeElement("Two Circles");
comp.Add(new PrimitiveElement("Black Circle"));
comp.Add(new PrimitiveElement("White Circle"));
root.Add(comp);
// "Component" Treenode
// Constructor
public DrawingElement(string name)
{
this.name = name;
}
// "Leaf"
// "Composite"
// Constructor
public CompositeElement(string name) : base(name)
{
}
Output
-+ Picture
--- Red Line
--- Blue Circle
--- Green Box
---+ Two Circles
----- Black Circle
----- White Circle
Hide code
definition
return to top
participants
• 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.
return to top
sample code in C#
This structural code demonstrates the Decorator pattern which
dynamically adds extra functionality to an existing object.
Hide code
using System;
namespace DoFactory.GangOfFour.Decorator.Structural
{
class MainApp
{
static void Main()
{
// Create ConcreteComponent and two Decorators
ConcreteComponent c = new ConcreteComponent();
ConcreteDecoratorA d1 = new ConcreteDecoratorA();
ConcreteDecoratorB d2 = new ConcreteDecoratorB();
// Link decorators
d1.SetComponent(c);
d2.SetComponent(d1);
d2.Operation();
// "Component"
// "ConcreteComponent"
// "Decorator"
// "ConcreteDecoratorA"
// "ConcreteDecoratorB"
void AddedBehavior()
{
}
}
}
Output
ConcreteComponent.Operation()
ConcreteDecoratorA.Operation()
ConcreteDecoratorB.Operation()
This real-world code demonstrates the Decorator pattern in which 'borrowable' functionality is
added to existing library items (books and videos).
Hide code
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Decorator.RealWorld
{
class MainApp
{
static void Main()
{
// Create book
Book book = new Book ("Worley", "Inside ASP.NET", 10);
book.Display();
// Create video
Video video = new Video ("Spielberg", "Jaws", 23, 92);
video.Display();
borrowvideo.Display();
// "Component"
// Property
public int NumCopies
{
get{ return numCopies; }
set{ numCopies = value; }
}
// "ConcreteComponent"
// Constructor
public Book(string author,string title,int numCopies)
{
this.author = author;
this.title = title;
this.NumCopies = numCopies;
}
// "ConcreteComponent"
// Constructor
public Video(string director, string title,
int numCopies, int playTime)
{
this.director = director;
this.title = title;
this.NumCopies = numCopies;
this.playTime = playTime;
}
// "Decorator"
abstract class Decorator : LibraryItem
{
protected LibraryItem libraryItem;
// Constructor
public Decorator(LibraryItem libraryItem)
{
this.libraryItem = libraryItem;
}
// "ConcreteDecorator"
// Constructor
public Borrowable(LibraryItem libraryItem)
: base(libraryItem)
{
}
Output
Book ------
Author: Worley
Title: Inside ASP.NET
# Copies: 10
Video -----
Director: Spielberg
Title: Jaws
# Copies: 23
Playtime: 92
Video -----
Director: Spielberg
Title: Jaws
# Copies: 21
Playtime: 92
borrower: Customer #1
borrower: Customer #2
Hide code
definition
return to top
participants
return to top
sample code in C#
using System;
namespace DoFactory.GangOfFour.Facade.Structural
{
class MainApp
{
public static void Main()
{
Facade facade = new Facade();
facade.MethodA();
facade.MethodB();
// "Subsystem ClassA"
class SubSystemOne
{
public void MethodOne()
{
Console.WriteLine(" SubSystemOne Method");
}
}
// Subsystem ClassB"
class SubSystemTwo
{
public void MethodTwo()
{
Console.WriteLine(" SubSystemTwo Method");
}
}
// Subsystem ClassC"
class SubSystemThree
{
public void MethodThree()
{
Console.WriteLine(" SubSystemThree Method");
}
}
// Subsystem ClassD"
class SubSystemFour
{
public void MethodFour()
{
Console.WriteLine(" SubSystemFour Method");
}
}
// "Facade"
class Facade
{
SubSystemOne one;
SubSystemTwo two;
SubSystemThree three;
SubSystemFour four;
public Facade()
{
one = new SubSystemOne();
two = new SubSystemTwo();
three = new SubSystemThree();
four = new SubSystemFour();
}
Output
MethodA() ----
SubSystemOne Method
SubSystemTwo Method
SubSystemFour Method
MethodB() ----
SubSystemTwo Method
SubSystemThree Method
This real-world code demonstrates the Facade pattern as a MortgageApplication object which
provides a simplified interface to a large subsystem of classes measuring the creditworthyness of
an applicant.
Hide code
using System;
namespace DoFactory.GangOfFour.Facade.RealWorld
{
// MainApp test application
class MainApp
{
static void Main()
{
// Facade
Mortgage mortgage = new Mortgage();
Console.WriteLine("\n" + customer.Name +
" has been " + (eligable ? "Approved" : "Rejected"));
// "Subsystem ClassA"
class Bank
{
public bool HasSufficientSavings(Customer c, int amount)
{
Console.WriteLine("Check bank for " + c.Name);
return true;
}
}
// "Subsystem ClassB"
class Credit
{
public bool HasGoodCredit(Customer c)
{
Console.WriteLine("Check credit for " + c.Name);
return true;
}
}
// "Subsystem ClassC"
class Loan
{
public bool HasNoBadLoans(Customer c)
{
Console.WriteLine("Check loans for " + c.Name);
return true;
}
}
class Customer
{
private string name;
// Constructor
public Customer(string name)
{
this.name = name;
}
// Property
public string Name
{
get{ return name; }
}
}
// "Facade"
class Mortgage
{
private Bank bank = new Bank();
private Loan loan = new Loan();
private Credit credit = new Credit();
return eligible;
}
}
}
Output
Ann McKinsey applies for $125,000.00 loan
Hide code
definition
return to top
participants
• Flyweight (Character)
o declares an interface through which flyweights can receive and act
on extrinsic state.
• ConcreteFlyweight (CharacterA, CharacterB, ..., CharacterZ)
o 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.
• UnsharedConcreteFlyweight ( not used )
o not all Flyweight subclasses need to be shared. The Flyweight
interface enables sharing, but it doesn't enforce it. It is common for
UnsharedConcreteFlyweight objects to have ConcreteFlyweight
objects as children at some level in the flyweight object structure (as
the Row and Column classes have).
• FlyweightFactory (CharacterFactory)
o creates and manages flyweight objects
o 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.
• Client (FlyweightApp)
o maintains a reference to flyweight(s).
o computes or stores the extrinsic state of flyweight(s).
return to top
sample code in C#
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Flyweight.Structural
{
// MainApp test application
class MainApp
{
static void Main()
{
// Arbitrary extrinsic state
int extrinsicstate = 22;
FlyweightFactory f = new FlyweightFactory();
Flyweight fy = f.GetFlyweight("Y");
fy.Operation(--extrinsicstate);
Flyweight fz = f.GetFlyweight("Z");
fz.Operation(--extrinsicstate);
UnsharedConcreteFlyweight fu = new
UnsharedConcreteFlyweight();
fu.Operation(--extrinsicstate);
// "FlyweightFactory"
class FlyweightFactory
{
private Hashtable flyweights = new Hashtable();
// Constructor
public FlyweightFactory()
{
flyweights.Add("X", new ConcreteFlyweight());
flyweights.Add("Y", new ConcreteFlyweight());
flyweights.Add("Z", new ConcreteFlyweight());
}
// "ConcreteFlyweight"
// "UnsharedConcreteFlyweight"
Output
ConcreteFlyweight: 21
ConcreteFlyweight: 20
ConcreteFlyweight: 19
UnsharedConcreteFlyweight: 18
This real-world code demonstrates the Flyweight pattern in which a relatively small number of
Character objects is shared many times by a document that has potentially many characters.
Hide code
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Flyweight.RealWorld
{
class MainApp
{
static void Main()
{
// Build a document with text
string document = "AAZZBBZB";
char[] chars = document.ToCharArray();
// extrinsic state
int pointSize = 10;
// "FlyweightFactory"
class CharacterFactory
{
private Hashtable characters = new Hashtable();
// "Flyweight"
// "ConcreteFlyweight"
// "ConcreteFlyweight"
// ... C, D, E, etc.
// "ConcreteFlyweight"
Output
A (pointsize 11)
A (pointsize 12)
Z (pointsize 13)
Z (pointsize 14)
B (pointsize 15)
B (pointsize 16)
Z (pointsize 17)
B (pointsize 18)
Hide code
return to top
participants
• Proxy (MathProxy)
o 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.
o provides an interface identical to Subject's so that a proxy can be
substituted for for the real subject.
o controls access to the real subject and may be responsible for
creating and deleting it.
o 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.
• Subject (IMath)
o defines the common interface for RealSubject and Proxy so that a
Proxy can be used anywhere a RealSubject is expected.
• RealSubject (Math)
o defines the real object that the proxy represents.
return to top
sample code in C#
using System;
namespace DoFactory.GangOfFour.Proxy.Structural
{
class MainApp
{
static void Main()
{
// Create proxy and request a service
Proxy proxy = new Proxy();
proxy.Request();
// "Subject"
abstract class Subject
{
public abstract void Request();
}
// "RealSubject"
// "Proxy"
realSubject.Request();
}
}
}
Output
Called RealSubject.Request()
This real-world code demonstrates the Proxy pattern for a Math object represented by a
MathProxy object.
Hide code
namespace DoFactory.GangOfFour.Proxy.RealWorld
{
class MainApp
{
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));
Console.WriteLine("4 * 2 = " + p.Mul(4, 2));
Console.WriteLine("4 / 2 = " + p.Div(4, 2));
// "Subject"
// "RealSubject"
// "Proxy Object"
public MathProxy()
{
math = new Math();
}
Output
4+2=6
4-2=2
4*2=8
4/2=2
definition
return to top
participants
• Handler (Approver)
o defines an interface for handling the requests
o (optional) implements the successor link
• ConcreteHandler (Director, VicePresident, President)
o handles requests it is responsible for
o can access its successor
o if the ConcreteHandler can handle the request, it does so; otherwise
it forwards the request to its successor
• Client (ChainApp)
o initiates the request to a ConcreteHandler object on the chain
return to top
sample code in C#
using System;
namespace DoFactory.GangOfFour.Chain.Structural
{
// MainApp test application
class MainApp
{
static void Main()
{
// Setup Chain of Responsibility
Handler h1 = new ConcreteHandler1();
Handler h2 = new ConcreteHandler2();
Handler h3 = new ConcreteHandler3();
h1.SetSuccessor(h2);
h2.SetSuccessor(h3);
// "Handler"
// "ConcreteHandler1"
// "ConcreteHandler3"
Output
ConcreteHandler1 handled request 2
ConcreteHandler1 handled request 5
ConcreteHandler2 handled request 14
ConcreteHandler3 handled request 22
ConcreteHandler2 handled request 18
ConcreteHandler1 handled request 3
ConcreteHandler3 handled request 27
ConcreteHandler3 handled request 20
This real-world code demonstrates the Chain of Responsibility pattern in which several linked
managers and executives can respond to a purchase request or hand it off to a superior. Each
position has can have its own set of rules which orders they can approve.
Hide code
using System;
namespace DoFactory.GangOfFour.Chain.RealWorld
{
class MainApp
{
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);
// "Handler"
// "ConcreteHandler"
// "ConcreteHandler"
// "ConcreteHandler"
// Request details
class Purchase
{
private int number;
private double amount;
private string purpose;
// Constructor
public Purchase(int number, double amount, string purpose)
{
this.number = number;
this.amount = amount;
this.purpose = purpose;
}
// Properties
public double Amount
{
get{ return amount; }
set{ amount = value; }
}
Output
Director Larry approved request# 2034
President Tammy approved request# 2035
Request# 2036 requires an executive meeting!
Hide code
definition
return to top
participants
• 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.
return to top
sample code in C#
using System;
namespace DoFactory.GangOfFour.Command.Structural
{
class MainApp
{
static void Main()
{
// Create receiver, command, and invoker
Receiver receiver = new Receiver();
Command command = new ConcreteCommand(receiver);
Invoker invoker = new Invoker();
// "Command"
// Constructor
public Command(Receiver receiver)
{
this.receiver = receiver;
}
// "ConcreteCommand"
// "Receiver"
class Receiver
{
public void Action()
{
Console.WriteLine("Called Receiver.Action()");
}
}
// "Invoker"
class Invoker
{
private Command command;
Output
Called Receiver.Action()
This real-world code demonstrates the Command pattern used in a simple calculator with
unlimited number of undo's and redo's. Note that in C# the word 'operator' is a keyword. Prefixing
it with '@' allows using it as an identifier.
Hide code
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Command.RealWorld
{
class MainApp
{
static void Main()
{
// Create user and let her compute
User user = new User();
user.Compute('+', 100);
user.Compute('-', 50);
user.Compute('*', 10);
user.Compute('/', 2);
// Undo 4 commands
user.Undo(4);
// Redo 3 commands
user.Redo(3);
// "Command"
// "ConcreteCommand"
// Constructor
public CalculatorCommand(Calculator calculator,
char @operator, int operand)
{
this.calculator = calculator;
this.@operator = @operator;
this.operand = operand;
}
public char Operator
{
set{ @operator = value; }
}
// "Receiver"
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"
class User
{
// Initializers
private Calculator calculator = new Calculator();
private ArrayList commands = new ArrayList();
Output
Current value = 100 (following + 100)
Current value = 50 (following - 50)
Current value = 500 (following * 10)
Current value = 250 (following / 2)
Hide code
return to top
definition
participants
• AbstractExpression (Expression)
o declares an interface for executing an operation
• TerminalExpression ( ThousandExpression, HundredExpression,
TenExpression, OneExpression )
o implements an Interpret operation associated with terminal symbols
in the grammar.
o an instance is required for every terminal symbol in the sentence.
• NonterminalExpression ( not used )
o one such class is required for every rule R ::= R1R2...Rn in the
grammar
o maintains instance variables of type AbstractExpression for each of
the symbols R1 through Rn.
o implements an Interpret operation for nonterminal symbols in the
grammar. Interpret typically calls itself recursively on the variables
representing R1 through Rn.
• Context (Context)
o contains information that is global to the interpreter
• Client (InterpreterApp)
o builds (or is given) an abstract syntax tree representing a particular
sentence in the language that the grammar defines. The abstract
syntax tree is assembled from instances of the
NonterminalExpression and TerminalExpression classes
o invokes the Interpret operation
return to top
sample code in C#
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Interpreter.Structural
{
class MainApp
{
static void Main()
{
Context context = new Context();
// Usually a tree
ArrayList list = new ArrayList();
// Interpret
foreach (AbstractExpression exp in list)
{
exp.Interpret(context);
}
class Context
{
}
// "AbstractExpression"
// "TerminalExpression"
// "NonterminalExpression"
Output
Called Terminal.Interpret()
Called Nonterminal.Interpret()
Called Terminal.Interpret()
Called Terminal.Interpret()
This real-world code demonstrates the Interpreter pattern which is used to convert a Roman
numeral to a decimal.
Hide code
// Interpreter pattern -- Real World example
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Interpreter.RealWorld
{
class MainApp
{
static void Main()
{
string roman = "MCMXXVIII";
Context context = new Context(roman);
// Interpret
foreach (Expression exp in tree)
{
exp.Interpret(context);
}
Console.WriteLine("{0} = {1}",
roman, context.Output);
// "Context"
class Context
{
private string input;
private int output;
// Constructor
public Context(string input)
{
this.input = input;
}
// Properties
public string Input
{
get{ return input; }
set{ input = value; }
}
// "AbstractExpression"
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);
}
}
// One checks for I, II, III, IV, V, VI, VI, VII, VIII, IX
// "TerminalExpression"
Output
MCMXXVIII = 1928
Hide code
definition
return to top
participants
• Iterator (AbstractIterator)
o defines an interface for accessing and traversing elements.
• ConcreteIterator (Iterator)
o implements the Iterator interface.
o keeps track of the current position in the traversal of the aggregate.
• Aggregate (AbstractCollection)
o defines an interface for creating an Iterator object
• ConcreteAggregate (Collection)
o implements the Iterator creation interface to return an instance of the
proper ConcreteIterator
return to top
sample code in C#
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Iterator.Structural
{
class MainApp
{
static void Main()
{
ConcreteAggregate a = new ConcreteAggregate();
a[0] = "Item A";
a[1] = "Item B";
a[2] = "Item C";
a[3] = "Item D";
// "Aggregate"
// "ConcreteAggregate"
// Property
public int Count
{
get{ return items.Count; }
}
// Indexer
public object this[int index]
{
get{ return items[index]; }
set{ items.Insert(index, value); }
}
}
// "Iterator"
// "ConcreteIterator"
// Constructor
public ConcreteIterator(ConcreteAggregate aggregate)
{
this.aggregate = aggregate;
}
return ret;
}
Output
Iterating over collection:
Item A
Item B
Item C
Item D
This real-world code demonstrates the Iterator pattern which is used to iterate over a collection of
items and skip a specific number of items each iteration.
Hide code
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Iterator.RealWorld
{
class MainApp
{
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");
collection[3] = new Item("Item 3");
collection[4] = new Item("Item 4");
collection[5] = new Item("Item 5");
collection[6] = new Item("Item 6");
collection[7] = new Item("Item 7");
collection[8] = new Item("Item 8");
// Create iterator
Iterator iterator = new Iterator(collection);
// Skip every other item
iterator.Step = 2;
class Item
{
string name;
// Constructor
public Item(string name)
{
this.name = name;
}
// Property
public string Name
{
get{ return name; }
}
}
// "Aggregate"
interface IAbstractCollection
{
Iterator CreateIterator();
}
// "ConcreteAggregate"
class Collection : IAbstractCollection
{
private ArrayList items = new ArrayList();
// Property
public int Count
{
get{ return items.Count; }
}
// Indexer
public object this[int index]
{
get{ return items[index]; }
set{ items.Add(value); }
}
}
// "Iterator"
interface IAbstractIterator
{
Item First();
Item Next();
bool IsDone{ get; }
Item CurrentItem{ get; }
}
// "ConcreteIterator"
// Constructor
public Iterator(Collection collection)
{
this.collection = collection;
}
// Properties
public int Step
{
get{ return step; }
set{ step = value; }
}
Hide code
definition
participants
• Mediator (IChatroom)
o defines an interface for communicating with Colleague objects
• ConcreteMediator (Chatroom)
o implements cooperative behavior by coordinating Colleague objects
o knows and maintains its colleagues
• Colleague classes (Participant)
o each Colleague class knows its Mediator object
o each colleague communicates with its mediator whenever it would
have otherwise communicated with another colleague
return to top
sample code in C#
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Mediator.Structural
{
// Mainapp test application
class MainApp
{
static void Main()
{
ConcreteMediator m = new ConcreteMediator();
m.Colleague1 = c1;
m.Colleague2 = c2;
// "Mediator"
// "ConcreteMediator"
// "Colleague"
// Constructor
public Colleague(Mediator mediator)
{
this.mediator = mediator;
}
}
// "ConcreteColleague1"
// "ConcreteColleague2"
Output
Colleague2 gets message: How are you?
Colleague1 gets message: Fine, thanks
This real-world code demonstrates the Mediator pattern facilitating loosely coupled
communication between different Participants registering with a Chatroom. The Chatroom is the
central hub through which all communication takes place. At this point only one-to-one
communication is implemented in the Chatroom, but would be trivial to change to one-to-many.
Hide code
// Mediator pattern -- Real World example
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Mediator.RealWorld
{
class MainApp
{
static void Main()
{
// Create chatroom
Chatroom chatroom = new Chatroom();
chatroom.Register(George);
chatroom.Register(Paul);
chatroom.Register(Ringo);
chatroom.Register(John);
chatroom.Register(Yoko);
// Chatting participants
Yoko.Send ("John", "Hi John!");
Paul.Send ("Ringo", "All you need is love");
Ringo.Send("George", "My sweet Lord");
Paul.Send ("John", "Can't buy me love");
John.Send ("Yoko", "My sweet love") ;
// "Mediator"
abstract class AbstractChatroom
{
public abstract void Register(Participant participant);
public abstract void Send(
string from, string to, string message);
}
// "ConcreteMediator"
participant.Chatroom = this;
}
// "AbstractColleague"
class Participant
{
private Chatroom chatroom;
private string name;
// Constructor
public Participant(string name)
{
this.name = name;
}
// Properties
public string Name
{
get{ return name; }
}
//" ConcreteColleague1"
//" ConcreteColleague2"
Output
To a Beatle: Yoko to John: 'Hi John!'
To a Beatle: Paul to Ringo: 'All you need is love'
To a Beatle: Ringo to George: 'My sweet Lord'
To a Beatle: Paul to John: 'Can't buy me love'
To a non-Beatle: John to Yoko: 'My sweet love'
Hide code
definition
return to top
participants
• Memento (Memento)
o 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.
o 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.
• Originator (SalesProspect)
o creates a memento containing a snapshot of its current internal state.
o uses the memento to restore its internal state
• Caretaker (Caretaker)
o is responsible for the memento's safekeeping
o never operates on or examines the contents of a memento.
return to top
sample code in C#
using System;
namespace DoFactory.GangOfFour.Memento.Structural
{
class MainApp
{
static void Main()
{
Originator o = new Originator();
o.State = "On";
class Originator
{
private string state;
// Property
public string State
{
get{ return state; }
set
{
state = value;
Console.WriteLine("State = " + state);
}
}
// "Memento"
class Memento
{
private string state;
// Constructor
public Memento(string state)
{
this.state = state;
}
// Property
public string State
{
get{ return state; }
}
}
// "Caretaker"
class Caretaker
{
private Memento memento;
// Property
public Memento Memento
{
set{ memento = value; }
get{ return memento; }
}
}
}
Output
State = On
State = Off
Restoring state:
State = On
This real-world code demonstrates the Memento pattern which temporarily saves and then
restores the SalesProspect's internal state.
Hide code
using System;
namespace DoFactory.GangOfFour.Memento.RealWorld
{
class MainApp
{
static void Main()
{
SalesProspect s = new SalesProspect();
s.Name = "Noel van Halen";
s.Phone = "(412) 256-0990";
s.Budget = 25000.0;
// "Originator"
class SalesProspect
{
private string name;
private string phone;
private double budget;
// Properties
public string Name
{
get{ return name; }
set
{
name = value;
Console.WriteLine("Name: " + name);
}
}
// "Memento"
class Memento
{
private string name;
private string phone;
private double budget;
// Constructor
public Memento(string name, string phone, double budget)
{
this.name = name;
this.phone = phone;
this.budget = budget;
}
// Properties
public string Name
{
get{ return name; }
set{ name = value; }
}
// "Caretaker"
class ProspectMemory
{
private Memento memento;
// Property
public Memento Memento
{
set{ memento = value; }
get{ return memento; }
}
}
}
Output
Name: Noel van Halen
Phone: (412) 256-0990
Budget: 25000
Saving state --
Restoring state --
Hide code
definition
return to top
participants
• Subject (Stock)
o knows its observers. Any number of Observer objects
may observe a subject
o provides an interface for attaching and detaching
Observer objects.
• ConcreteSubject (IBM)
o stores state of interest to ConcreteObserver
o sends a notification to its observers when its state
changes
• Observer (IInvestor)
o defines an updating interface for objects that should be
notified of changes in a subject.
• ConcreteObserver (Investor)
o maintains a reference to a ConcreteSubject object
o stores state that should stay consistent with the
subject's
o implements the Observer updating interface to keep its
state consistent with the subject's
return to top
sample code in C#
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Observer.Structural
{
class MainApp
{
static void Main()
{
// Configure Observer pattern
ConcreteSubject s = new ConcreteSubject();
s.Attach(new ConcreteObserver(s,"X"));
s.Attach(new ConcreteObserver(s,"Y"));
s.Attach(new ConcreteObserver(s,"Z"));
// "Subject"