Design patterns are recurring solutions to software design problems you find again and again in real-world application development. Patterns are about design and interaction of objects, as well as providing a communication platform concerning elegant, reusable solutions to commonly encountered programming challenges.
See also here for a detailed explanation of patterns
Creational
Factory pattern
Abstract factory pattern
Builder pattern
Prototype pattern
Singleton
Structural
Decorator pattern
Composite pattern
Facade pattern
Behavioral
Strategy pattern
Chain of responsibility
Visitor pattern
Factory pattern
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
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();
// Wait for user input
Console.Read();
}
}
// "AbstractFactory"
abstract class AbstractFactory
{
public abstract AbstractProductA CreateProductA();
public abstract AbstractProductB CreateProductB();
}
// "ConcreteFactory1"
class ConcreteFactory1 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA1();
}
public override AbstractProductB CreateProductB()
{
return new ProductB1();
}
}
// "ConcreteFactory2"
class ConcreteFactory2 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA2();
}
public override AbstractProductB CreateProductB()
{
return new ProductB2();
}
}
// "AbstractProductA"
abstract class AbstractProductA
{
}
// "AbstractProductB"
abstract class AbstractProductB
{
public abstract void Interact(AbstractProductA a);
}
// "ProductA1"
class ProductA1 : AbstractProductA
{
}
// "ProductB1"
class ProductB1 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Console.WriteLine(this.GetType().Name +
" interacts with " + a.GetType().Name);
}
}
// "ProductA2"
class ProductA2 : AbstractProductA
{
}
// "ProductB2"
class ProductB2 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Console.WriteLine(this.GetType().Name +
" interacts with " + a.GetType().Name);
}
}
// "Client" - the interaction environment of the products
class Client
{
private AbstractProductA AbstractProductA;
private AbstractProductB AbstractProductB;
// Constructor
public Client(AbstractFactory factory)
{
AbstractProductB = factory.CreateProductB();
AbstractProductA = factory.CreateProductA();
}
public void Run()
{
AbstractProductB.Interact(AbstractProductA);
}
}
}
Abstract Factory pattern
Separate the construction of a complex object from its representation so that the same construction process can create different representations.
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Builder.Structural
{
// MainApp test application
public class MainApp
{
public static void Main()
{
// Create director and builders
Director director = new Director();
Builder b1 = new ConcreteBuilder1();
Builder b2 = new ConcreteBuilder2();
// Construct two products
director.Construct(b1);
Product p1 = b1.GetResult();
p1.Show();
director.Construct(b2);
Product p2 = b2.GetResult();
p2.Show();
// Wait for user
Console.Read();
}
}
// "Director"
class Director
{
// Builder uses a complex series of steps
public void Construct(Builder builder)
{
builder.BuildPartA();
builder.BuildPartB();
}
}
// "Builder"
abstract class Builder
{
public abstract void BuildPartA();
public abstract void BuildPartB();
public abstract Product GetResult();
}
// "ConcreteBuilder1"
class ConcreteBuilder1 : Builder
{
private Product product = new Product();
public override void BuildPartA()
{
product.Add("PartA");
}
public override void BuildPartB()
{
product.Add("PartB");
}
public override Product GetResult()
{
return product;
}
}
// "ConcreteBuilder2"
class ConcreteBuilder2 : Builder
{
private Product product = new Product();
public override void BuildPartA()
{
product.Add("PartX");
}
public override void BuildPartB()
{
product.Add("PartY");
}
public override Product GetResult()
{
return product;
}
}
// "Product"
class Product
{
ArrayList parts = new ArrayList();
public void Add(string part)
{
parts.Add(part);
}
public void Show()
{
Console.WriteLine("nProduct Parts -------");
foreach (string part in parts)
Console.WriteLine(part);
}
}
}
Prototype pattern
Specify the kind of objects to create using a prototypical instance, and create new objects by copying this prototype.
// Prototype pattern -- Structural example
using System;
namespace DoFactory.GangOfFour.Prototype.Structural
{
// MainApp startup class for Structural
// Prototype Design Pattern.
class MainApp
{
// Entry point into console application.
static void Main()
{
// Create two instances and clone each
ConcretePrototype1 p1 = new ConcretePrototype1("I");
ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();
Console.WriteLine("Cloned: {0}", c1.Id);
ConcretePrototype2 p2 = new ConcretePrototype2("II");
ConcretePrototype2 c2 = (ConcretePrototype2)p2.Clone();
Console.WriteLine("Cloned: {0}", c2.Id);
// Wait for user
Console.ReadKey();
}
}
// The 'Prototype' abstract class
abstract class Prototype
{
private string _id;
// Constructor
public Prototype(string id)
{
this._id = id;
}
// Gets id
public string Id
{
get { return _id; }
}
public abstract Prototype Clone();
}
// A 'ConcretePrototype' class
class ConcretePrototype1 : Prototype
{
// Constructor
public ConcretePrototype1(string id) : base(id) { }
// Returns a shallow copy
public override Prototype Clone()
{
return (Prototype)this.MemberwiseClone();
}
}
// A 'ConcretePrototype' class
class ConcretePrototype2 : Prototype
{
// Constructor
public ConcretePrototype2(string id) : base(id)
{
}
// Returns a shallow copy
public override Prototype Clone()
{
return (Prototype)this.MemberwiseClone();
}
}
}
Singleton pattern
Ensure a class has only one instance and provide a global point of access to it.
// Singleton pattern -- Structural example
using System;
namespace DoFactory.GangOfFour.Singleton.Structural
{
//
// MainApp startup class for Structural
// Singleton Design Pattern.
//
class MainApp
{
//
// Entry point into console application.
//
static void Main()
{
// Constructor is protected -- cannot use new
Singleton s1 = Singleton.Instance();
Singleton s2 = Singleton.Instance();
// Test for same instance
if (s1 == s2)
{
Console.WriteLine("Objects are the same instance");
}
// Wait for user
Console.ReadKey();
}
}
//
// The 'Singleton' class
//
class Singleton
{
private static Singleton _instance;
// Constructor is 'protected'
protected Singleton()
{
}
public static Singleton Instance()
{
// Uses lazy initialization.
// Note: this is not thread safe.
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
}
Decorator pattern
Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
using System;
namespace DoFactory.GangOfFour.Decorator.Structural
{
// MainApp test application
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();
// Wait for user
Console.Read();
}
}
// "Component"
abstract class Component
{
public abstract void Operation();
}
// "ConcreteComponent"
class ConcreteComponent : Component
{
public override void Operation()
{
Console.WriteLine("ConcreteComponent.Operation()");
}
}
// "Decorator"
abstract class Decorator : Component
{
protected Component component;
public void SetComponent(Component component)
{
this.component = component;
}
public override void Operation()
{
if (component != null)
{
component.Operation();
}
}
}
// "ConcreteDecoratorA"
class ConcreteDecoratorA : Decorator
{
private string addedState;
public override void Operation()
{
base.Operation();
addedState = "New State";
Console.WriteLine("ConcreteDecoratorA.Operation()");
}
}
// "ConcreteDecoratorB"
class ConcreteDecoratorB : Decorator
{
public override void Operation()
{
base.Operation();
AddedBehavior();
Console.WriteLine("ConcreteDecoratorB.Operation()");
}
void AddedBehavior()
{
}
}
}
Composite pattern
Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Composite.Structural
{
// MainApp test application
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"));
Composite comp = new Composite("Composite X");
comp.Add(new Leaf("Leaf XA"));
comp.Add(new Leaf("Leaf XB"));
root.Add(comp);
root.Add(new Leaf("Leaf C"));
// Add and remove a leaf
Leaf leaf = new Leaf("Leaf D");
root.Add(leaf);
root.Remove(leaf);
// Recursively display tree
root.Display(1);
// Wait for user
Console.Read();
}
}
// "Component"
abstract class Component
{
protected string name;
// Constructor
public Component(string name)
{
this.name = name;
}
public abstract void Add(Component c);
public abstract void Remove(Component c);
public abstract void Display(int depth);
}
// "Composite"
class Composite : Component
{
private ArrayList children = new ArrayList();
// Constructor
public Composite(string name) : base(name)
{
}
public override void Add(Component component)
{
children.Add(component);
}
public override void Remove(Component component)
{
children.Remove(component);
}
public override void Display(int depth)
{
Console.WriteLine(new String('-', depth) + name);
// Recursively display child nodes
foreach (Component component in children)
{
component.Display(depth + 2);
}
}
}
// "Leaf"
class Leaf : Component
{
// Constructor
public Leaf(string name) : base(name)
{
}
public override void Add(Component c)
{
Console.WriteLine("Cannot add to a leaf");
}
public override void Remove(Component c)
{
Console.WriteLine("Cannot remove from a leaf");
}
public override void Display(int depth)
{
Console.WriteLine(new String('-', depth) + name);
}
}
}
Facade pattern
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.
using System;
namespace DoFactory.GangOfFour.Factory.Structural
{
///
/// MainApp startup class for Structural
/// Factory Method Design Pattern.
///
class MainApp
{
///
/// Entry point into console application.
///
static void Main()
{
// An array of creators
Creator[] creators = new Creator[2];
creators[0] = new ConcreteCreatorA();
creators[1] = new ConcreteCreatorB();
// Iterate over creators and create products
foreach (Creator creator in creators)
{
Product product = creator.FactoryMethod();
Console.WriteLine("Created {0}",
product.GetType().Name);
}
// Wait for user
Console.ReadKey();
}
}
///
/// The 'Product' abstract class
///
abstract class Product
{
}
///
/// A 'ConcreteProduct' class
///
class ConcreteProductA : Product
{
}
///
/// A 'ConcreteProduct' class
///
class ConcreteProductB : Product
{
}
///
/// The 'Creator' abstract class
///
abstract class Creator
{
public abstract Product FactoryMethod();
}
///
/// A 'ConcreteCreator' class
///
class ConcreteCreatorA : Creator
{
public override Product FactoryMethod()
{
return new ConcreteProductA();
}
}
///
/// A 'ConcreteCreator' class
///
class ConcreteCreatorB : Creator
{
public override Product FactoryMethod()
{
return new ConcreteProductB();
}
}
}
Strategy pattern
Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
using System;
namespace DoFactory.GangOfFour.Strategy.Structural
{
// MainApp test application
class MainApp
{
static void Main()
{
Context context;
// Three contexts following different strategies
context = new Context(new ConcreteStrategyA());
context.ContextInterface();
context = new Context(new ConcreteStrategyB());
context.ContextInterface();
context = new Context(new ConcreteStrategyC());
context.ContextInterface();
// Wait for user
Console.Read();
}
}
// "Strategy"
abstract class Strategy
{
public abstract void AlgorithmInterface();
}
// "ConcreteStrategyA"
class ConcreteStrategyA : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine(
"Called ConcreteStrategyA.AlgorithmInterface()");
}
}
// "ConcreteStrategyB"
class ConcreteStrategyB : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine(
"Called ConcreteStrategyB.AlgorithmInterface()");
}
}
// "ConcreteStrategyC"
class ConcreteStrategyC : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine(
"Called ConcreteStrategyC.AlgorithmInterface()");
}
}
// "Context"
class Context
{
Strategy strategy;
// Constructor
public Context(Strategy strategy)
{
this.strategy = strategy;
}
public void ContextInterface()
{
strategy.AlgorithmInterface();
}
}
}
Chain of responsibility
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.
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);
// Generate and process request
int[] requests = {2, 5, 14, 22, 18, 3, 27, 20};
foreach (int request in requests)
{
h1.HandleRequest(request);
}
// Wait for user
Console.Read();
}
}
// "Handler"
abstract class Handler
{
protected Handler successor;
public void SetSuccessor(Handler successor)
{
this.successor = successor;
}
public abstract void HandleRequest(int request);
}
// "ConcreteHandler1"
class ConcreteHandler1 : Handler
{
public override void HandleRequest(int request)
{
if (request >= 0 && request < 10)
{
Console.WriteLine("{0} handled request {1}",
this.GetType().Name, request);
}
else if (successor != null)
{
successor.HandleRequest(request);
}
}
}
// "ConcreteHandler2"
class ConcreteHandler2 : Handler
{
public override void HandleRequest(int request)
{
if (request >= 10 && request < 20)
{
Console.WriteLine("{0} handled request {1}",
this.GetType().Name, request);
}
else if (successor != null)
{
successor.HandleRequest(request);
}
}
}
// "ConcreteHandler3"
class ConcreteHandler3 : Handler
{
public override void HandleRequest(int request)
{
if (request >= 20 && request < 30)
{
Console.WriteLine("{0} handled request {1}",
this.GetType().Name, request);
}
else if (successor != null)
{
successor.HandleRequest(request);
}
}
}
}
Visitor pattern
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.
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Visitor.Structural
{
// MainApp test application
class MainApp
{
static void Main()
{
// Setup structure
ObjectStructure o = new ObjectStructure();
o.Attach(new ConcreteElementA());
o.Attach(new ConcreteElementB());
// Create visitor objects
ConcreteVisitor1 v1 = new ConcreteVisitor1();
ConcreteVisitor2 v2 = new ConcreteVisitor2();
// Structure accepting visitors
o.Accept(v1);
o.Accept(v2);
// Wait for user
Console.Read();
}
}
// "Visitor"
abstract class Visitor
{
public abstract void VisitConcreteElementA(
ConcreteElementA concreteElementA);
public abstract void VisitConcreteElementB(
ConcreteElementB concreteElementB);
}
// "ConcreteVisitor1"
class ConcreteVisitor1 : Visitor
{
public override void VisitConcreteElementA(
ConcreteElementA concreteElementA)
{
Console.WriteLine("{0} visited by {1}",
concreteElementA.GetType().Name, this.GetType().Name);
}
public override void VisitConcreteElementB(
ConcreteElementB concreteElementB)
{
Console.WriteLine("{0} visited by {1}",
concreteElementB.GetType().Name, this.GetType().Name);
}
}
// "ConcreteVisitor2"
class ConcreteVisitor2 : Visitor
{
public override void VisitConcreteElementA(
ConcreteElementA concreteElementA)
{
Console.WriteLine("{0} visited by {1}",
concreteElementA.GetType().Name, this.GetType().Name);
}
public override void VisitConcreteElementB(
ConcreteElementB concreteElementB)
{
Console.WriteLine("{0} visited by {1}",
concreteElementB.GetType().Name, this.GetType().Name);
}
}
// "Element"
abstract class Element
{
public abstract void Accept(Visitor visitor);
}
// "ConcreteElementA"
class ConcreteElementA : Element
{
public override void Accept(Visitor visitor)
{
visitor.VisitConcreteElementA(this);
}
public void OperationA()
{
}
}
// "ConcreteElementB"
class ConcreteElementB : Element
{
public override void Accept(Visitor visitor)
{
visitor.VisitConcreteElementB(this);
}
public void OperationB()
{
}
}
// "ObjectStructure"
class ObjectStructure
{
private ArrayList elements = new ArrayList();
public void Attach(Element element)
{
elements.Add(element);
}
public void Detach(Element element)
{
elements.Remove(element);
}
public void Accept(Visitor visitor)
{
foreach (Element e in elements)
{
e.Accept(visitor);
}
}
}
}










