Skip to content

Instantly share code, notes, and snippets.

@NDiiong
Created August 12, 2020 06:42
Show Gist options
  • Save NDiiong/d70ae46fe4299436d9f34b0360ea2158 to your computer and use it in GitHub Desktop.
Save NDiiong/d70ae46fe4299436d9f34b0360ea2158 to your computer and use it in GitHub Desktop.
22 Design Patterns in C#
class Abstraction
{
Bridge bridge;
public Abstraction(Bridge implementation)
{
bridge = implementation;
}
public string Operation()
{
return "Abstraction <<< BRIDGE >>>> " + bridge.OperationImp();
}
}
interface Bridge
{
string OperationImp();
}
class ImplementationA : Bridge
{
public string OperationImp() { return "ImplementationA"; }
}
class ImplementationB : Bridge
{
public string OperationImp() { return "ImplementationB"; }
}
class Client
{
static void Main()
{
Console.WriteLine("Bridge Pattern\n");
Console.WriteLine(new Abstraction(new ImplementationA()).Operation());
Console.WriteLine(new Abstraction(new ImplementationB()).Operation());
/* Output
Bridge Pattern
Abstraction <<< BRIDGE >>>> ImplementationA
Abstraction <<< BRIDGE >>>> ImplementationB
*/
}
}
class Client
{
private ITarget _target;
public Client(ITarget target)
{
_target = target;
}
public void MakeRequest()
{
_target.MethodA();
}
}
interface ITarget
{
void MethodA();
}
class Adaptee
{
public void MethodB()
{
Console.WriteLine("MethodB called");
}
}
class Adapter : ITarget
{
Adaptee _adaptee = new Adaptee();
public void MethodA()
{
_adaptee.MethodB();
}
}
class MealDirector // Director
{
public void MakeMeal(IMealBuilder mealBuilder)
{ mealBuilder.AddSandwich(); mealBuilder.AddDrink(); }
}
interface IMealBuilder // IBuilder
{
public void AddSandwich(); public void AddDrink(); public Meal GetMeal();
} // Concrete Builders
class VegetarianMealBuilder : IMealBuilder
{
Meal meal = new Meal();
public Meal GetMeal() { return meal; }
public void AddSandwich() { meal.Sandwich = "Vegetarian Sandwich"; }
public void AddDrink() { meal.Drink = "Water"; }
}
class BBQMealBuilder : IMealBuilder
{
Meal meal = new Meal();
public Meal GetMeal() { return meal; }
public void AddSandwich() { meal.Sandwich = "BBQ Burger"; }
public void AddDrink() { meal.Drink = "Coke"; }
}
class Meal // Product
{
public string Sandwich { get; set; }
public string Drink { get; set; }
}
public class Client
{
public static void Main()
{ // Create one director and two builders, then Construct two products
MealDirector director = new MealDirector();
IMealBuilder b1 = new VegetarianMealBuilder();
IMealBuilder b2 = new BBQMealBuilder();
director.MakeMeal(b1);
director.MakeMeal(b2);
Meal p1 = b1.GetMeal();
Meal p1 = b2.GetMeal();
}
}
class Handler
{
Handler successor; int id;
public int Limit { get { return id * 1000; } }
public Handler(int id, Handler handler)
{
this.id = id;
successor = handler;
}
public string HandleRequest(int data)
{
if (data < Limit)
return "Request for " + data + " handled at level " + id;
else if (successor != null)
return successor.HandleRequest(data);
else return ("Request for " + data + " handled BY DEFAULT at level " + id);
}
}
class Client
{
static void Main()
{
Handler successor = null;
for (int i = 5; i > 0; i--)
{
successor = new Handler(i, successor);
Console.WriteLine("Handler " + i + " deals up to a limit of " + successor.Limit);
}
int[] a = { 50, 2000, 1500, 10000, 175, 4500 };
foreach (int i in a)
Console.WriteLine(successor.HandleRequest(i));
/*Output:
Handler 5 deals up to a limit of 5000
Handler 4 deals up to a limit of 4000
Handler 3 deals up to a limit of 3000
Handler 2 deals up to a limit of 2000
Handler 1 deals up to a limit of 1000
Request for 50 handled at level 1
Request for 2000 handled at level 3
Request for 1500 handled at level 2
Request for 10000 handled BY DEFAULT at level 5
Request for 175 handled at level 1
Request for 4500 handled at level 5
*/
}
}
/* ICommand and Implementaion */
public interface ICommand
{
void Execute();
}
public class OpenSwitchCommand : ICommand
{
// -State
private Light light;
public OpenSwitchCommand(Light light)
{
this.light = light;
}
public void Execute() { light.PowerOff(); }
}
/* The Invoker class */
public class Switch
{
ICommand _openedCommand;
public Switch(ICommand openedCommand)
{
this._openedCommand = openedCommand;
}
// Invoke by calling command.Execute
public void Open() { this._openedCommand.Execute(); }
}
/* The Receiver class */
public class Light
{
public void PowerOn() { Console.WriteLine("The light is on"); }
}
public class Client
{
public static void Main(string[] arguments)
{
// create receiver and pass to command implementation
Light lamp = new Light();
ICommand switchOpen = new OpenSwitchCommand(lamp);
//Pass reference to instance of the Command objects to the switch (invoker)
Switch mySwitch = new Switch(switchOpen);
//Switch (the Invoker) will invoke the Execute() (the Command) on the command object -
_openedCommand.Execute();
mySwitch.Open();
}
}
// IComponent
public interface IGraphic
{
void Print();
}
// Component
public class Ellipse : IGraphic
{
public void Print() { Console.WriteLine("Ellipse"); }
}
// Composite
public class CompositeGraphic : IGraphic
{
private readonly List<IGraphic> graphics = new List<IGraphic>();
public void Add(IGraphic graphic)
{
graphics.Add(graphic);
}
public void Delete(IGraphic graphic)
{
graphics.Remove(graphic);
}
public void Print()
{
foreach (var childGraphic in graphics)
childGraphic.Print();
}
}
class Client
{
static void Main(string[] args)
{
var compositeGraphic1 = new CompositeGraphic();
var compositeGraphic2 = new CompositeGraphic();
compositeGraphic1.Add(new Ellipse());
compositeGraphic2.Add(new Ellipse());
compositeGraphic2.Add(compositeGraphic1);
// prints 2 times "Ellipse"
compositeGraphic2.Print();
}
}
interface IComponent
{
string Operation();
}
class Component : IComponent
{
public string Operation() { return "I am walking "; }
}
class DecoratorA : IComponent
{
IComponent component;
public DecoratorA(IComponent c) { component = c; }
public string Operation()
{
string s = component.Operation();
s += "and listening to Classic FM ";
return s;
}
}
class DecoratorB : IComponent
{
IComponent component;
public DecoratorB(IComponent c) { component = c; }
public string Operation()
{
string s = component.Operation();
s += "to school ";
return s;
}
}
class Client
{
static void Main()
{
IComponent component = new Component();
IComponent aDecorated = new DecoratorA(component);
IComponent bDecorated = new DecoratorB(component);
IComponent abDecorated = new DecoratorB(new DecoratorA(component));
}
}
namespace FacadeLib
{
internal class SubsystemA
{
internal string A1() { return "Subsystem A, Method A1\n"; }
}
internal class SubsystemB
{
internal string B1() { return "Subsystem B, Method B1\n"; }
}
internal class SubsystemC
{
internal string C1() { return "Subsystem C, Method C1\n"; }
}
public static class Facade
{
static SubsystemA a = new SubsystemA();
static SubsystemB b = new SubsystemB();
static SubsystemC c = new SubsystemC();
public static void Operation()
{
Console.WriteLine("Operation 1\n" +
a.A1() + b.B1()) + c.C1();
}
}
}
class Client
{
public static void Main()
{
FacadeLib.Facade.Operation();
}
}
using System;
using System.Collections;
class FactoryPattern
{
interface IProduct { string ShipFrom(); }
class ProductA : IProduct
{
public String ShipFrom()
{
return " from South Africa";
}
}
class ProductB : IProduct
{
public String ShipFrom()
{
return "from Spain";
}
}
class DefaultProduct : IProduct
{
public String ShipFrom()
{
return "not available";
}
}
class Creator
{
public IProduct FactoryMethod(int month)
{
if (month >= 4 && month <= 11)
return new ProductA();
else
if (month == 1 || month == 2 || month == 12)
return new ProductB();
else
return new DefaultProduct();
}
}
static void Main()
{
Creator c = new Creator();
IProduct product;
for (int i = 1; i <= 12; i++)
{
product = c.FactoryMethod(i);
Console.WriteLine("Avocados " + product.ShipFrom());
}
}
}
interface IFactory
{
IProductA CreateProductA();
IProductB CreateProductB();
}
interface IProductA { }
interface IProductB { }
// Concrete Factories
class Factory1 : IFactory
{
public IProductA CreateProductA() { return new ProductA1(); }
public IProductB CreateProductB() { return new ProductB1(); }
}
class Factory2 : IFactory
{
public IProductA CreateProductA() { return new ProductA2(); }
public IProductB CreateProductB() { return new ProductB2(); }
}
// Concrete Products
class ProductA1 : IProductA { }
class ProductA2 : IProductA { }
class ProductB1 : IProductB { }
class ProductB2 : IProductB { }
public interface IFlyweight
{
void Load(string filename);
void Display(int row, int col);
}
public struct Flyweight : IFlyweight
{
// Intrinsicstate
Image pThumbnail;
public void Load(string filename)
{
pThumbnail = GetThumbnail(filename);
}
public void Display(int row, int col)
{
// Draw by using extrinsic state
DrawImage(pThumbnail, row, col);
}
}
public class FlyweightFactory
{
// Keeps an indexed list of IFlyweight objects in existance
Dictionary<string, IFlyweight> flyweights = new Dictionary<string, IFlyweight>();
public FlyweightFactory()
{
flyweights.Clear();
}
public IFlyweight this[string index]
{
get
{
if (!flyweights.ContainsKey(index))
flyweights[index] = new Flyweight();
return flyweights[index];
}
}
}
public class Client
{
public static void Main()
{
FlyweightFactory factory = new FlyweightFactory();
factory["file1"].Load("file1.png");
// draw same image in two different places (extrinsic state)
factory["file1"].Display(1, 3);
factory["file1"].Display(5, 10);
}
}
// Simplest iterator
class MonthCollection : IEnumerable
{
string[] months = {"January", "February", "March", "April","May",
"June", "July", "August", "September","October","November", "December"};
public IEnumerator GetEnumerator()
{
// Generates values from the collection
foreach (string element in months)
yield return element;
}
}
class Client
{
static void Main()
{
MonthCollection collection = new MonthCollection();
// Consumes values generated from collection's GetEnumeror method
foreach (string n in collection)
Console.Write(n + " ");
Console.WriteLine("\n");
}
}
class Mediator
{
public delegate void Callback(string message, string from);
Callback respond;
public void SignOn(Callback method) { respond += method; }
// Send is implemented as a broadcast
public void Send(string message, string from)
{
respond(message, from);
Console.WriteLine();
}
}
class Colleague
{
Mediator mediator;
private string name;
public Colleague(Mediator mediator, string name)
{
this.mediator = mediator;
mediator.SignOn(Receive);
this.name = name;
}
public void Receive(string message, string from)
{
Console.WriteLine(name + " received from " + from + ": " + message);
}
public void Send(string message)
{
Console.WriteLine("Send (From " + name + "): " + message);
mediator.Send(message, name);
}
}
class Client
{
static void Main()
{
Mediator m = new Mediator();
Colleague head1 = new Colleague(m, "John"); Colleague head2 = new Colleague(m, "Lucy");
head1.Send("Meeting on Tuesday, please all ack");
head2.Send("Ack");
/* Output: Send (From John): Meeting on Tuesday, please all ack
John received from John: Meeting on Tuesday, please all ack
Lucy received from John: Meeting on Tuesday, please all ack
Send (From Lucy): Ack
John received from Lucy: Ack
Lucy received from Lucy: Ack
*/
}
}
class Originator
{
private string _state;
public Memento CreateMemento()
{
return new Memento(_state);
}
public void SetMemento(Memento memento)
{
Console.WriteLine("Restoring state...");
State = memento.State;
}
}
class Memento
{
private string _state;
public Memento(string state)
{
this._state = state;
}
public string State { get { return _state; } }
}
class Caretaker
{
public Memento Memento { get; set; }
}
class Client
{
static void Main()
{
Originator o = new Originator();
o.State = "On";
Caretaker c = new Caretaker();
c.Memento = o.CreateMemento();
o.State = "Off";
o.SetMemento(c.Memento);
}
}
public interface IObservable
{
void Attach(IObserver observer);
void Detach(IObserver observer);
}
public interface IObserver
{
void Update();
}
public class Observable : IObservable
{
private List<IObserver> observers = new List<IObserver>();
public void Attach(IObserver observer) { observers.Add(observer); }
public void Detach(IObserver observer) { observers.Remove(observer); }
private void Notify()
{
foreach (IObserver observer in observers) observer.Update();
}
public void ChangeState()
{/* change state and notify observers */
Notify();
}
}
public class Observer : IObserver
{
public void Update() { /* change state */}
}
public class Client
{
public static void Main()
{
Observable observable = new Observable();
observable.Attach(new Observer());
observable.ChangeState();
}
}
// Serialization is used for the deep copy option
[Serializable()]
public abstract class IPrototype<T>
{
public T Clone()
{
return (T)this.MemberwiseClone(); // Shallow copy
}
public T DeepCopy()
{ // Deep Copy
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, this);
stream.Seek(0, SeekOrigin.Begin);
T copy = (T)formatter.Deserialize(stream);
stream.Close();
return copy;
}
}
public interface ISubject
{
string Request();
}
public class Subject : ISubject
{
public string Request()
{
return "Subject Request Choose left door\n";
}
}
public class VirtualProxy : ISubject
{
Subject subject;
public string Request()
{
// A Virtual Proxy creates the object only on its first
// method call
if (subject == null)
{
subject = new Subject();
}
return "Proxy: Call to " + subject.Request();
}
}
class Client
{
static void Main()
{
// no Subject is created
ISubject subject = new VirtualProxy();
// only one object is created on multiple use
Console.WriteLine(subject.Request());
Console.WriteLine(subject.Request());
}
}
using System;
class SingletonPattern
{
// The public property protects the private constructor
public sealed class Singleton
{
// Private Constructor
Singleton() { }
// Private object instantiated with private constructor
static readonly Singleton instance = new Singleton();
// Public static property to get the object
public static Singleton UniqueInstance
{
get { return instance; }
}
}
static void Main()
{
Singleton s1 = Singleton.UniqueInstance;
Singleton s2 = Singleton.UniqueInstance;
if (s1 == s2)
{
Console.WriteLine("Objects are the same instance");
}
}
}
interface IState { int Move(Context context); }
class MoveUpState : IState
{
public int Move(Context context)
{
context.Counter += 2;
if (context.Counter > Context.UpperLimit) { context.State = new MoveDownState(); }
return context.Counter;
}
}
class MoveDownState : IState
{
public int Move(Context context)
{
context.Counter -= 2;
if (context.Counter < Context.LowerLimit) { context.State = new MoveUpState(); }
return context.Counter;
}
}
class Context
{
const int UpperLimit = 10, LowerLimit = 0;
public IState State { get; set; }
public int Counter = UpperLimit;
public int Request() { return State.MoveUp(this); }
}
static class Client
{
static void Main()
{
Context context = new Context();
context.State = new MoveDownState();
for (int i = 5; i <= 25; i++)
{
Console.Write(context.Request(command) + " ");
}
}
}
public interface ICalculateStrategy
{
int Calculate(int value1, int value2);
}
public class MinusStrategy : ICalculateStrategy
{
public int Calculate(int value1, int value2)
{
return value1 - value2;
}
}
public class PlusStrategy : ICalculateStrategy
{
public int Calculate(int value1, int value2)
{
return value1 + value2;
}
}
public class CalculateContext
{
public ICalculateStrategy Strategy { get; set; }
public CalculateContext(ICalculateStrategy strategy)
{
Strategy = strategy;
}
public int Calculate(int value1, int value2)
{
return Strategy.Calculate(value1, value2);
}
}
public class Client
{
public static void Main()
{
CalculateContext client = new CalculateContext(new MinusStrategy());
Console.WriteLine("Minus: " + client.Calculate(7, 1)); // Outputs 6
// Change the strategy
client.Strategy = new PlusStrategy();
Console.WriteLine("Plus: " + client.Calculate(7, 1)); // Outputs 8
}
}
class Algorithm
{
public void TemplateMethod(IPrimitives a)
{
string s = a.Operation1() + a.Operation2();
Console.WriteLine(s);
}
}
interface IPrimitives
{
string Operation1();
string Operation2();
}
class ClassA : IPrimitives
{
public string Operation1() { return "ClassA:Op1 "; }
public string Operation2() { return "ClassA:Op2 "; }
}
class ClassB : IPrimitives
{
public string Operation1() { return "ClassB:Op1 "; }
public string Operation2() { return "ClassB.Op2 "; }
}
class TemplateMethodPattern
{
static void Main()
{
Algorithm m = new Algorithm();
m.TemplateMethod(new ClassA());
m.TemplateMethod(new ClassB());
}
}
interface IExpression /* Element */
{
void Accept(IExpressionVisitor visitor);
}
class Literal : IExpression
{
internal double Value { get; set; }
public Literal(double value) { this.Value = value; }
public void Accept(IExpressionVisitor visitor)
{
visitor.Visit(this);
}
}
class Addition : IExpression
{
internal IExpression Left { get; set; }
internal IExpression Right { get; set; }
public Addition(IExpression left, IExpression right)
{
this.Left = left;
this.Right = right;
}
public void Accept(IExpressionVisitor visitor)
{
visitor.Visit(this);
}
}
interface IExpressionVisitor
{
void Visit(Literal literal);
void Visit(Addition addition);
}
class ExpressionPrinter : IExpressionVisitor
{
StringBuilder sb;
public ExpressionPrinter(StringBuilder sb) { this.sb = sb; }
public void Visit(Literal literal) { sb.Append(literal.Value); }
public void Visit(Addition addition)
{
sb.Append("(");
addition.Left.Accept(this);
sb.Append("+");
addition.Right.Accept(this);
sb.Append(")");
}
}
public class Client
{
public static void Main(string[] args)
{ // emulate 1+2+3
var e = new Addition(new Addition(new Literal(1), new Literal(2)), new Literal(3));
var sb = new StringBuilder();
e.Accept(new ExpressionPrinter(sb));
Console.WriteLine(sb); /* OUTPUT: ((1+2)+3)*/
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment