Table of Contents


Creational Patterns

Patterns that abstract the object instantiation process.

1. Abstract Factory

Concept: Create families of related or dependent objects without specifying concrete classes.

interface GUIFactory {
    fun createButton(): Button
    fun createCheckbox(): Checkbox
}
 
class MacGUIFactory : GUIFactory {
    override fun createButton(): Button { return MacButton() }
    override fun createCheckbox(): Checkbox { return MacCheckbox() }
}
 
class WindowsGUIFactory : GUIFactory {
    override fun createButton(): Button { return WindowsButton() }
    override fun createCheckbox(): Checkbox { return WindowsCheckbox() }
}
 
interface Button {
    fun paint()
}
class MacButton : Button {
    override fun paint() { System.out.println("Mac Button"); }
}
class WindowsButton implements Button {
    public void paint() { System.out.println("Windows Button"); }
}
 
interface Checkbox {
    fun check()
}
class MacCheckbox : Checkbox {
    override fun check() { System.out.println("Mac Checkbox"); }
}
class WindowsCheckbox : Checkbox {
    override fun check() { System.out.println("Windows Checkbox"); }
}
 
// Usage:
val factory = MacGUIFactory()
val button = factory.createButton()
val checkbox = factory.createCheckbox()
button.paint()
checkbox.check()
 

⬆️ Back to Table of Contents

2. Builder

Concept: Separate object construction from representation.

class House {
    private final String walls;
    private final String roof;
 
    private House(Builder b) {
        this.walls = b.walls;
        this.roof = b.roof;
    }
 
    static class Builder {
        private String walls;
        private String roof;
 
        Builder walls(String walls) { ... }
        Builder roof(String roofType) { ... }
 
        House build() { ... }
}
 
// Usage:
House house = new House.Builder().walls("Brick").roof("Tiles").build();

⬆️ Back to Table of Contents

3. Factory Method

Concept: Factory method delegates instance creation to subclasses. This differs from the Abstract Factory pattern where the factory itself is instantiated by the client and then passed to the factory method.

interface Shape { void draw(); }
 
class Circle implements Shape { public void draw(){...} }
 
class ShapeFactory {
  Shape createShape(String type) {
    if(type.equals("circle")) return new Circle();
    else return new Square();
}
 
// Usage:
Shape shape = factory.createShape("circle");
 

⬆️ Back to Table of Contents

4. Prototype

Concept: Create new objects by cloning existing ones.

interface Prototype {
    fun clone(): Prototype
}
 
class Concrete : Prototype {
    override fun clone(): Prototype { return ConcretePrototype(this) }
}
 
// Usage:
val p1 = Concrete()
val copy = p1.clone()

⬆️ Back to Table of Contents

5. Singleton

Concept: Ensure only one instance of a class is created.

class Singleton private constructor() {
    companion object {
        val instance = Singleton()
    }
}
 
// Usage:
val s = Singleton.instance

⬆️ Back to Table of Contents

Structural Patterns

Patterns that ease design by identifying relationships between entities.

1. Adapter

Concept: Bridge incompatible interfaces.

interface MediaPlayer {
    fun play()
}
 
class MP3Player : MediaPlayer {
    override fun play() { println("Playing MP3") }
}
 
class MP4Adapter : MediaPlayer {
    val mp3 = MP3Player()
 
    override fun play() { mp3.play() }
}
 
// Usage:
val player = MP4Adapter()
player.play()
 

⬆️ Back to Table of Contents

2. Facade

Concept: Provide simplified interface for complex subsystems.

class HomeTheaterFacade {
    val projector = Projector()
    val amplifier = Amplifier()
 
    fun watchMovie() {
        projector.on()
        amplifier.on()
    }
 
    fun endMovie() {
        projector.off()
        amplifier.off()
    }
}
 
// Usage:
val theater = HomeTheaterFacade()
theater.watchMovie()
theater.endMovie()

⬆️ Back to Table of Contents

3. Decorator

Concept: Add responsibilities dynamically.

interface Coffee {
    fun cost(): Int
}
 
class Espresso : Coffee {
    override fun cost(): Int { return 2 }
}
 
class MilkDecorator : Coffee {
    val coffee: Coffee
 
    constructor(coffee: Coffee) { this.coffee = coffee }
    override fun cost(): Int { return coffee.cost() + 1 }
}
 
class SweetnerDecorator : Coffee {
    val coffee: Coffee
 
    constructor(coffee: Coffee) { this.coffee = coffee }
    override fun cost(): Int { return coffee.cost() + 1 }
}
 
// Usage:
val coffee = SweetnerDecorator(MilkDecorator(Espresso()))
println(coffee.cost())
val coffee2 = MilkDecorator(Espresso())
println(coffee2.cost())

⬆️ Back to Table of Contents

4. Bridge

Concept: Decouple abstraction from implementation and hide implementation details from client.

interface Color {
    void applyColor();
}
 
// Concrete Implementor
class RedColor implements Color {
    public void applyColor() { System.out.println("Applying Red"); }
}
 
class BlueColor implements Color {
    public void applyColor() { System.out.println("Applying Blue"); }
}
 
// Abstraction
abstract class Shape {
    protected Color color;
    Shape(Color c) { this.color = c; }
    abstract void draw();
}
 
class Circle extends Shape {
    Circle(Color c) { super(c); }
    public void draw() { System.out.println("Drawing Circle"); }
}
 
class Square extends Shape {
    Square(Color c) { super(c); }
    public void draw() { System.out.println("Drawing Square"); }
}
 
// Usage:
val redCircle = Circle(RedColor())
redCircle.draw()
val blueCircle = Circle(BlueColor())
blueCircle.draw()
val redSquare = Square(RedColor())
redSquare.draw()
val blueSquare = Square(BlueColor())
blueSquare.draw()

⬆️ Back to Table of Contents

5. Composite

Concept: Compose objects into tree structures to represent part-whole hierarchies.

interface Component { void display(); }
 
class Leaf implements Component {
    String name;
    Leaf(String name) { this.name = name; }
    public void display() { System.out.println(name); }
}
 
class Composite implements Component {
    List<Component> components = new ArrayList<>();
    void add(Component c) { components.add(c); }
    public void display() { components.forEach(Component::display); }
}
 
// Usage:
Composite root = new Composite();
root.add(new Leaf("Leaf 1"));
Composite sub = new Composite();
sub.add(new Leaf("Leaf A"));
root.add(sub);
 
root.display();
 

⬆️ Back to Table of Contents

6. Proxy

Concept: Provide a surrogate or placeholder for another object to control access to it.

interface Internet { void connect(); }
 
class RealInternet implements Internet {
    public void connect() { System.out.println("Connected to Internet."); }
}
 
class ProxyInternet implements Internet {
    RealInternet real;
    String user;
 
    Proxy(String user) { this.user = user; }
 
    public void connect() {
        if (userHasAccess())
            new RealInternet().connect();
        else
            System.out.println("Access Denied!");
    }
}
 
// Usage:
Internet internet = new ProxyInternet("guest");
internet.connect();
 

⬆️ Back to Table of Contents

7. Flyweight

Concept: Share objects to reduce memory usage.

interface Shape { void draw(int x, int y); }
 
class Circle implements Shape {
    String color;
    Circle(String color) { this.color = color; }
    public void draw(int x, int y) {
        System.out.println(color + " circle at " + x + ", " + y);
    }
}
 
class ShapeFactory {
    static Map<String, Shape> shapes = new HashMap<>();
 
    static Shape getCircle(String color) {
        return shapes.computeIfAbsent(color, Circle::new);
    }
}
 
// Usage:
Shape red = factory.getCircle("Red");
red.draw(10, 20);
 
Shape anotherRed = factory.getCircle("Red"); // reuses previous object
anotherRed.draw(20, 40);
 
 

⬆️ Back to Table of Contents


Structural Patterns

Patterns that compose classes or objects into larger structures.

  • Adapter
  • Bridge
  • Composite
  • Decorator
  • Facade
  • Flyweight
  • Proxy

Behavioral Patterns

Patterns defining object interactions and responsibilities between objects.

1. Strategy

Concept: Encapsulate interchangeable behaviors and allow them to be used interchangeably.

interface PaymentStrategy { fun pay(amount: Int) }
 
class CreditCardPayment : PaymentStrategy {
  override fun pay(amount: Int) { System.out.println("Paid by Credit"); }
}
 
class PaypalPayment : PaymentStrategy {
  override fun pay(amount: Int) { System.out.println("Paid by Paypal"); }
}
 
// Usage:
val payment = Payment(CreditCardPayment())
payment.execute()
 
val payment2 = Payment(PaypalPayment())
payment2.execute()
 
 

⬆️ Back to Table of Contents

2. Observer

Concept: Notify objects about changes in state of another object.

interface Observer { fun update() }
 
class WeatherStation {
  val observers = mutableListOf<Observer>()
 
  fun addObserver(observer: Observer) { observers.add(observer) }
 
  fun notifyObservers() { observers.forEach(Observer::update) }
}
 
class WeatherObserver : Observer {
  override fun update() { println("Weather updated") }
}
 
// Usage:
val weatherStation = WeatherStation()
val weatherObserver = WeatherObserver()
weatherStation.addObserver(weatherObserver)
weatherStation.notifyObservers()
 

3. Strategy

Concept: Encapsulate algorithms, interchangeable.

interface SortStrategy { fun sort() }
 
class QuickSort : SortStrategy {
  override fun sort() { println("Quick sorting") }
}
 
class Context(strategy: SortStrategy) {
  fun execute() { strategy.sort() }
}
 
// Usage:
val ctx = Context(QuickSort())
ctx.execute()
 

⬆️ Back to Table of Contents

4. Chain of Responsibility

Concept: Chain commands together.

interface Handler { 
    fun handle(request: String) 
    fun setNext(handler: Handler)
}
 
class ConcreteHandler1 : Handler {
    var next: Handler? = null
    override fun handle(request: String) { println("ConcreteHandler1 handled request") }
    override fun setNext(handler: Handler) { next = handler }
}
 
class ConcreteHandler2 : Handler {
   var next: Handler? = null
   override fun handle(request: String) { println("ConcreteHandler2 handled request") }
   override fun setNext(handler: Handler) { next = handler }
}
 
// Usage:
val handler1 = ConcreteHandler1()
val handler2 = ConcreteHandler2()
handler1.setNext(handler2)
handler1.handle("request")
 

⬆️ Back to Table of Contents

5. Command

Concept: Encapsulate a request as an object and pass it to the invoker.

interface Command { fun execute() }
 
class ConcreteCommand : Command {
    override fun execute() { println("ConcreteCommand executed") }
}
 
class Invoker {
    val command: Command
 
    constructor(command: Command) { this.command = command }
 
    fun run() { command.execute() }
}
 
// Usage:
val invoker = Invoker(ConcreteCommand())
invoker.run()
 

⬆️ Back to Table of Contents

6. Interpreter

Concept: Define a grammar for a language and implement an interpreter to parse sentences in the language.

interface Expression { fun interpret() }
 
class TerminalExpression : Expression {
    override fun interpret() { println("TerminalExpression interpreted") }
}
 
class NonTerminalExpression : Expression {
    override fun interpret() { println("NonTerminalExpression interpreted") }
}
 
// Usage:
val expression = NonTerminalExpression()
expression.interpret()  
 

⬆️ Back to Table of Contents

7. Iterator

Concept: Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

interface Iterator { fun next(): Any? }
 
class ConcreteIterator : Iterator {
    override fun next(): Any? { return null }
}   
 
// Usage:
val iterator = ConcreteIterator()
iterator.next()
 

⬆️ Back to Table of Contents

8. Mediator

Concept: Define an object that encapsulates how a set of objects interact.

interface Mediator { fun send(message: String) }    
 
class ConcreteMediator : Mediator {
    override fun send(message: String) { println("Mediator sent message: $message") }
}
 
// Usage:
val mediator = ConcreteMediator()
mediator.send("Hello")  
 

⬆️ Back to Table of Contents

9. Memento

Concept: Capture and restore an object’s state.

interface Memento { fun getState(): String }
 
class ConcreteMemento : Memento {
    override fun getState(): String { return "State" }
}
 
// Usage:
val memento = ConcreteMemento()
memento.getState()
 

⬆️ Back to Table of Contents

10. State

Concept: Allow an object to change its behavior when its internal state changes.

interface State { fun handle() }
 
class ConcreteState : State {
    override fun handle() { println("ConcreteState handled") }
}
 
// Usage:
val state = ConcreteState()
state.handle()
 

⬆️ Back to Table of Contents

11. Template Method

Concept: Define the program skeleton of an algorithm in a method, deferring some steps to subclasses.

abstract class Game {
    abstract fun initialize()
    abstract fun startPlay()
    abstract fun endPlay()
}
 
class Cricket : Game {
    override fun initialize() { println("Cricket Game Initialized! Start playing.") }
    override fun startPlay() { println("Cricket Game Started. Enjoy the game!") }
    override fun endPlay() { println("Cricket Game Finished!") }
}
 
// Usage:
val game = Cricket()
game.play()
 

⬆️ Back to Table of Contents

12. Visitor

Concept: Represent an operation to be performed on the elements of an object structure.

interface Visitor { fun visit(element: Element) }
 
 
class ConcreteVisitor : Visitor {
    override fun visit(element: Element) { println("ConcreteVisitor visited element") }
}
 
// Usage:
val visitor = ConcreteVisitor()
visitor.visit(Element())
 

⬆️ Back to Table of Contents

Behavioral Patterns (Full list)

  • Chain of Responsibility
  • Command
  • Interpreter
  • Iterator
  • Mediator
  • Memento
  • Observer
  • State
  • Strategy
  • Template Method
  • Visitor

Summary

CreationalStructuralBehavioral
Abstract FactoryAdapterChain of Responsibility
BuilderBridgeCommand
Factory MethodCompositeInterpreter
PrototypeDecoratorIterator
SingletonFacadeMediator
DecoratorMemento
FlyweightObserver
FacadeState
ProxyStrategy
FlyweightTemplate Method
ProxyVisitor