Monday, March 2, 2026

Behavioral Patterns

 

Behavioral patterns focus on communication between objects and how responsibilities are distributed.

1) Observer Pattern

Notifies multiple objects when one object changes state.

Example

Event notification system.

using System;
using System.Collections.Generic;

public interface IObserver
{
    void Update(string message);
}

public class Subscriber : IObserver
{
    private string _name;

    public Subscriber(string name)
    {
        _name = name;
    }

    public void Update(string message)
    {
        Console.WriteLine(_name + " received: " + message);
    }
}

public class Publisher
{
    private List<IObserver> _observers = new List<IObserver>();

    public void Subscribe(IObserver observer)
    {
        _observers.Add(observer);
    }

    public void Notify(string message)
    {
        foreach (var observer in _observers)
        {
            observer.Update(message);
        }
    }
}

// Usage
Publisher pub = new Publisher();
pub.Subscribe(new Subscriber("User1"));
pub.Notify("New Notification");

2) Strategy Pattern

Defines a family of algorithms and makes them interchangeable.

Example

Different payment methods.

public interface IPaymentStrategy
{
    void Pay(int amount);
}

public class CreditCardPayment : IPaymentStrategy
{
    public void Pay(int amount)
    {
        Console.WriteLine("Paid " + amount + " using Credit Card");
    }
}

public class UpiPayment : IPaymentStrategy
{
    public void Pay(int amount)
    {
        Console.WriteLine("Paid " + amount + " using UPI");
    }
}

public class ShoppingCart
{
    private IPaymentStrategy _paymentStrategy;

    public ShoppingCart(IPaymentStrategy paymentStrategy)
    {
        _paymentStrategy = paymentStrategy;
    }

    public void Checkout(int amount)
    {
        _paymentStrategy.Pay(amount);
    }
}

// Usage
ShoppingCart cart = new ShoppingCart(new UpiPayment());
cart.Checkout(1000);

3) Command Pattern

Encapsulates a request as an object.

Example

public interface ICommand
{
    void Execute();
}

public class Light
{
    public void On()
    {
        Console.WriteLine("Light ON");
    }
}

public class LightOnCommand : ICommand
{
    private Light _light;

    public LightOnCommand(Light light)
    {
        _light = light;
    }

    public void Execute()
    {
        _light.On();
    }
}

// Usage
Light light = new Light();
ICommand command = new LightOnCommand(light);
command.Execute();

4) Chain of Responsibility Pattern

Passes request along a chain of handlers.

Example

public abstract class Handler
{
    protected Handler _next;

    public void SetNext(Handler next)
    {
        _next = next;
    }

    public abstract void HandleRequest(int level);
}

public class LevelOneHandler : Handler
{
    public override void HandleRequest(int level)
    {
        if (level == 1)
            Console.WriteLine("Handled by Level 1");
        else if (_next != null)
            _next.HandleRequest(level);
    }
}

5) Mediator Pattern

Controls communication between objects.

Example

public class ChatRoom
{
    public static void ShowMessage(string user, string message)
    {
        Console.WriteLine(user + ": " + message);
    }
}

6) State Pattern

Changes behavior when internal state changes.

Example

public interface IState
{
    void Handle();
}

public class StartState : IState
{
    public void Handle()
    {
        Console.WriteLine("Machine Started");
    }
}

7) Template Method Pattern

Defines skeleton of algorithm in base class.

Example

public abstract class DataProcessor
{
    public void Process()
    {
        ReadData();
        ProcessData();
        SaveData();
    }

    protected abstract void ReadData();
    protected abstract void ProcessData();

    protected void SaveData()
    {
        Console.WriteLine("Data Saved");
    }
}

8) Iterator Pattern

Provides sequential access without exposing structure.

Example: foreach in C# uses Iterator internally.


9) Memento Pattern

Saves and restores object state.


10) Visitor Pattern

Adds new operations without modifying classes.


11) Interpreter Pattern

Defines grammar and interpreter for language.


Simple Understanding

Observer → Notification system
Strategy → Change algorithm at runtime
Command → Request as object
Chain → Pass request step by step
Mediator → Central communication
State → Behavior changes by state
Template → Fixed algorithm structure
Iterator → Loop through collection
Memento → Undo feature
Visitor → Add new operation
Interpreter → Language parsing

Structural Patterns

 

Structural patterns focus on how classes and objects are composed to form larger structures.

1) Adapter Pattern

Converts one interface into another expected interface.

Example

Old printer class does not match new interface.

// Target interface
public interface IPrinter
{
    void Print();
}

// Existing class (incompatible)
public class OldPrinter
{
    public void PrintOld()
    {
        Console.WriteLine("Printing from Old Printer");
    }
}

// Adapter
public class PrinterAdapter : IPrinter
{
    private OldPrinter _oldPrinter = new OldPrinter();

    public void Print()
    {
        _oldPrinter.PrintOld();
    }
}

// Usage
IPrinter printer = new PrinterAdapter();
printer.Print();

2) Bridge Pattern

Separates abstraction from implementation.

Example

Remote control working with different TVs.

public interface ITV
{
    void On();
}

public class SonyTV : ITV
{
    public void On()
    {
        Console.WriteLine("Sony TV ON");
    }
}

public class SamsungTV : ITV
{
    public void On()
    {
        Console.WriteLine("Samsung TV ON");
    }
}

public class Remote
{
    protected ITV _tv;

    public Remote(ITV tv)
    {
        _tv = tv;
    }

    public void TurnOn()
    {
        _tv.On();
    }
}

// Usage
Remote remote = new Remote(new SonyTV());
remote.TurnOn();

3) Composite Pattern

Treats individual objects and groups of objects uniformly.

Example

File and Folder structure.

public interface IFileSystem
{
    void Show();
}

public class File : IFileSystem
{
    public void Show()
    {
        Console.WriteLine("File");
    }
}

public class Folder : IFileSystem
{
    private List<IFileSystem> _items = new List<IFileSystem>();

    public void Add(IFileSystem item)
    {
        _items.Add(item);
    }

    public void Show()
    {
        Console.WriteLine("Folder:");
        foreach (var item in _items)
        {
            item.Show();
        }
    }
}

// Usage
Folder folder = new Folder();
folder.Add(new File());
folder.Add(new File());
folder.Show();

4) Decorator Pattern

Adds new behavior to an object dynamically.

Example

Adding extra features to coffee.

public interface ICoffee
{
    string GetDescription();
}

public class SimpleCoffee : ICoffee
{
    public string GetDescription()
    {
        return "Plain Coffee";
    }
}

public class MilkDecorator : ICoffee
{
    private ICoffee _coffee;

    public MilkDecorator(ICoffee coffee)
    {
        _coffee = coffee;
    }

    public string GetDescription()
    {
        return _coffee.GetDescription() + " + Milk";
    }
}

// Usage
ICoffee coffee = new MilkDecorator(new SimpleCoffee());
Console.WriteLine(coffee.GetDescription());

5) Facade Pattern

Provides simplified interface to a complex system.

Example

public class CPU
{
    public void Start() => Console.WriteLine("CPU Started");
}

public class Memory
{
    public void Load() => Console.WriteLine("Memory Loaded");
}

public class ComputerFacade
{
    private CPU _cpu = new CPU();
    private Memory _memory = new Memory();

    public void StartComputer()
    {
        _cpu.Start();
        _memory.Load();
        Console.WriteLine("Computer Ready");
    }
}

// Usage
ComputerFacade computer = new ComputerFacade();
computer.StartComputer();

6) Flyweight Pattern

Reduces memory usage by sharing common objects.

Example

public class Circle
{
    public string Color { get; set; }

    public Circle(string color)
    {
        Color = color;
    }

    public void Draw()
    {
        Console.WriteLine("Drawing " + Color + " circle");
    }
}

Instead of creating many same-color objects, reuse existing ones.


7) Proxy Pattern

Controls access to another object.

Example

public interface IImage
{
    void Display();
}

public class RealImage : IImage
{
    public RealImage()
    {
        Console.WriteLine("Loading Image...");
    }

    public void Display()
    {
        Console.WriteLine("Displaying Image");
    }
}

public class ProxyImage : IImage
{
    private RealImage _realImage;

    public void Display()
    {
        if (_realImage == null)
            _realImage = new RealImage();

        _realImage.Display();
    }
}

// Usage
IImage image = new ProxyImage();
image.Display();

Summary (Simple Understanding)

Adapter → Converts interface
Bridge → Separates abstraction & implementation
Composite → Tree structure (part-whole)
Decorator → Adds extra behavior
Facade → Simplifies complex system
Flyweight → Shares objects to save memory
Proxy → Controls access

Creational Design Patterns

Creational patterns deal with object creation mechanisms.


1) Singleton Pattern

Ensures only one instance of a class exists.

Example

Used for logging, configuration, database connection, etc.

public class Logger
{
    private static Logger _instance;

    private Logger() { }

    public static Logger GetInstance()
    {
        if (_instance == null)
            _instance = new Logger();

        return _instance;
    }

    public void Log(string message)
    {
        Console.WriteLine(message);
    }
}

// Usage
Logger log1 = Logger.GetInstance();
Logger log2 = Logger.GetInstance();

Console.WriteLine(log1 == log2); // True (same instance)

2) Factory Method Pattern

Creates object without exposing instantiation logic.

Example

Creating different types of vehicles.

public interface IVehicle
{
    void Drive();
}

public class Car : IVehicle
{
    public void Drive()
    {
        Console.WriteLine("Car Driving");
    }
}

public class Bike : IVehicle
{
    public void Drive()
    {
        Console.WriteLine("Bike Riding");
    }
}

public class VehicleFactory
{
    public static IVehicle GetVehicle(string type)
    {
        if (type == "Car")
            return new Car();
        else if (type == "Bike")
            return new Bike();
        else
            return null;
    }
}

// Usage
IVehicle vehicle = VehicleFactory.GetVehicle("Car");
vehicle.Drive();

3) Abstract Factory Pattern

Creates families of related objects.

Example

Creating Windows and Mac UI elements.

public interface IButton
{
    void Render();
}

public class WindowsButton : IButton
{
    public void Render()
    {
        Console.WriteLine("Windows Button");
    }
}

public class MacButton : IButton
{
    public void Render()
    {
        Console.WriteLine("Mac Button");
    }
}

public interface IUIFactory
{
    IButton CreateButton();
}

public class WindowsFactory : IUIFactory
{
    public IButton CreateButton()
    {
        return new WindowsButton();
    }
}

public class MacFactory : IUIFactory
{
    public IButton CreateButton()
    {
        return new MacButton();
    }
}

// Usage
IUIFactory factory = new WindowsFactory();
IButton button = factory.CreateButton();
button.Render();

4) Builder Pattern

Builds complex object step by step.

Example

Building a House object.

public class House
{
    public string Walls { get; set; }
    public string Roof { get; set; }
}

public class HouseBuilder
{
    private House _house = new House();

    public HouseBuilder BuildWalls()
    {
        _house.Walls = "Concrete Walls";
        return this;
    }

    public HouseBuilder BuildRoof()
    {
        _house.Roof = "Steel Roof";
        return this;
    }

    public House GetHouse()
    {
        return _house;
    }
}

// Usage
House house = new HouseBuilder()
                .BuildWalls()
                .BuildRoof()
                .GetHouse();

5) Prototype Pattern

Creates new object by copying existing object.

Example

public class Person : ICloneable
{
    public string Name { get; set; }

    public object Clone()
    {
        return this.MemberwiseClone();
    }
}

// Usage
Person p1 = new Person { Name = "Naresh" };
Person p2 = (Person)p1.Clone();

Console.WriteLine(p2.Name);

Summary (Simple Understanding)

Singleton → One object only
Factory → Create object based on condition
Abstract Factory → Create related object families
Builder → Build complex object step by step
Prototype → Copy existing object

What is design pattern?

Design Pattern is a reusable solution to a common problem in software design.
It is not ready-made code, but a template or best practice to solve recurring design problems.
In simple words:
A design pattern tells how to structure classes and objects to solve a problem in a clean and maintainable way.

Types of Design Patterns (GoF – Gang of Four)
Design patterns are mainly divided into 3 categories:

1) Creational Patterns
Used to create objects in a proper and flexible way.
Singleton – Only one instance of a class is created.
Factory Method – Creates objects without specifying exact class.
Abstract Factory – Creates families of related objects.
Builder – Builds complex objects step by step.
Prototype – Creates new objects by copying existing object.

2) Structural Patterns
Used to organize classes and objects into larger structures.
Adapter – Converts one interface into another.
Bridge – Separates abstraction from implementation.
Composite – Treats individual objects and groups uniformly.
Decorator – Adds new behavior to objects dynamically.
Facade – Provides simple interface to complex system.
Flyweight – Reduces memory usage by sharing objects.
Proxy – Controls access to another object.

3) Behavioral Patterns
Used to manage communication between objects.
Observer – Notifies multiple objects when state changes.
Strategy – Defines family of algorithms and makes them interchangeable.
Command – Encapsulates a request as an object.
Chain of Responsibility – Passes request along a chain of handlers.
Mediator – Controls communication between objects.
State – Changes behavior based on internal state.
Template Method – Defines skeleton of algorithm.
Iterator – Access elements sequentially.
Memento – Saves and restores object state.
Visitor – Adds new operation without changing classes.
Interpreter – Defines grammar for a language.