Design Patterns & Practices  

GoF Design Patterns C# (23)

Creational Patterns (5)

  1. Singleton – single instance

  
    public class Singleton { private static Singleton _instance; private Singleton(){} public static Singleton Instance => _instance ??= new Singleton(); }
  
  1. Factory Method – object creation without specifying a class

  
    public abstract class Shape{public abstract void Draw();}
public class Circle:Shape{public override void Draw()=>Console.WriteLine("Circle");}
public static class Factory{public static Shape GetShape(string type)=>type=="Circle"?new Circle():throw new ArgumentException();}
  
  1. Abstract Factory – family of related objects

  
    public interface IButton{void Paint();}
public class WinButton:IButton{public void Paint()=>Console.WriteLine("Windows Button");}
public interface IGUIFactory{IButton CreateButton();}
public class WinFactory:IGUIFactory{public IButton CreateButton()=>new WinButton();}
  
  1. Builder – step-by-step object creation

  
    public class Car{public string Engine; public string Wheels;}
public class CarBuilder{Car car=new(); public CarBuilder AddEngine(string e){car.Engine=e;return this;} public CarBuilder AddWheels(string w){car.Wheels=w;return this;} public Car Build()=>car;}
  
  1. Prototype – clone objects

  
    public class Prototype{public int X; public Prototype Clone()=> (Prototype)this.MemberwiseClone();}
  

Structural Patterns (7)

  1. Adapter – convert interface

  
    public interface ITarget{void Request();}
public class Adaptee{public void SpecificRequest()=>Console.WriteLine("Specific");}
public class Adapter:ITarget{Adaptee a=new(); public void Request()=>a.SpecificRequest();}
  
  1. Decorator – add behavior dynamically

  
    public abstract class Coffee{public abstract string GetDescription();}
public class SimpleCoffee:Coffee{public override string GetDescription()=> "Simple";}
public class MilkDecorator:Coffee{Coffee c; public MilkDecorator(Coffee c){this.c=c;} public override string GetDescription()=>c.GetDescription()+", Milk";}
  
  1. Facade – simplify subsystem

  
    class SubA{public void A()=>Console.WriteLine("A");} class SubB{public void B()=>Console.WriteLine("B");}
class Facade{SubA a=new(); SubB b=new(); public void Operation(){a.A();b.B();}}
  
  1. Bridge – decouple abstraction & implementation

  
    public interface IRenderer{void RenderCircle(int x,int y,int radius);}
public class VectorRenderer:IRenderer{public void RenderCircle(int x,int y,int r)=>Console.WriteLine("Vector Circle");}
public class Circle{IRenderer renderer; int x,y,r; public Circle(int x,int y,int r,IRenderer renderer){this.x=x;this.y=y;this.r=r;this.renderer=renderer;} public void Draw()=>renderer.RenderCircle(x,y,r);}
  
  1. Composite – tree structure

  
    public abstract class Component{public abstract void Operation();}
public class Leaf:Component{public override void Operation()=>Console.WriteLine("Leaf");}
public class Composite:Component{List<Component> children=new(); public void Add(Component c)=>children.Add(c); public override void Operation(){foreach(var c in children)c.Operation();}}
  
  1. Flyweight – share objects

  
    class Flyweight{public string SharedState; public Flyweight(string s){SharedState=s;}}
class FlyweightFactory{Dictionary<string,Flyweight> flyweights=new(); public Flyweight Get(string key){if(!flyweights.ContainsKey(key))flyweights[key]=new Flyweight(key);return flyweights[key];}}
  
  1. Proxy – control access

  
    public interface ISubject{void Request();}
public class RealSubject:ISubject{public void Request()=>Console.WriteLine("Real Request");}
public class Proxy:ISubject{RealSubject real=new(); public void Request()=>real.Request();}
  

Behavioral Patterns (11)

  1. Observer – notify dependents

  
    public interface IObserver{void Update();}
public class ConcreteObserver:IObserver{public void Update()=>Console.WriteLine("Notified");}
public class Subject{List<IObserver> observers=new(); public void Attach(IObserver o)=>observers.Add(o); public void Notify()=>observers.ForEach(o=>o.Update());}
  
  1. Strategy – interchangeable algorithms

  
    public interface IStrategy{void Execute();}
public class StrategyA:IStrategy{public void Execute()=>Console.WriteLine("A");}
public class Context{IStrategy s; public Context(IStrategy s){this.s=s;} public void Execute()=>s.Execute();}
  
  1. Command – encapsulate requests

  
    public interface ICommand{void Execute();}
public class Light{public void On()=>Console.WriteLine("Light On");}
public class LightOnCommand:ICommand{Light l;public LightOnCommand(Light l){this.l=l;}public void Execute()=>l.On();}
  
  1. State – change behavior based on state

  
    public interface IState{void Handle();}
public class StateA:IState{public void Handle()=>Console.WriteLine("A");}
public class Context{IState s; public void SetState(IState state)=>s=state; public void Request()=>s.Handle();}
  
  1. Mediator – centralize communication

  
    public interface IMediator{void Send(string msg, Colleague c);}
public class ConcreteMediator:IMediator{public List<Colleague> colleagues=new(); public void Send(string msg, Colleague c){foreach(var col in colleagues) if(col!=c)col.Receive(msg);}}
public abstract class Colleague{protected IMediator mediator; public Colleague(IMediator m){mediator=m;} public abstract void Receive(string msg);}
  
  1. Chain of Responsibility – request passes along the chain

  
    public abstract class Handler{public Handler next; public void SetNext(Handler h)=>next=h; public abstract void Handle(int req);}
public class ConcreteHandler:Handler{public override void Handle(int req){if(req<10)Console.WriteLine(req); else next?.Handle(req);}}
  
  1. Template Method – algorithm skeleton

  
    public abstract class AbstractClass{public void TemplateMethod(){Step1();Step2();} public abstract void Step1(); public abstract void Step2();}
  
  1. Iterator – traverse collection

  
    var list=new List<int>{1,2,3}; foreach(var i in list)Console.WriteLine(i);
  
  1. Visitor – operation on object structure

  
    public interface IVisitor{void Visit(Element e);}
public abstract class Element{public abstract void Accept(IVisitor v);}
public class ConcreteElement:Element{public override void Accept(IVisitor v)=>v.Visit(this);}
  
  1. Interpreter – interpret language

  
    public interface IExpression{int Interpret();} 
public class Number: IExpression{int n;public Number(int n){this.n=n;} public int Interpret()=>n;}
  
  1. Memento – capture object state

  
    public class Memento{public string State; public Memento(string s){State=s;}}
public class Originator{public string State; public Memento Save()=>new(State); public void Restore(Memento m)=>State=m.State;}