Design Patterns With Examples
Design Patterns With Examples
Creational Patterns
Description: Ensures a class has only one instance and provides a global point of access to it.
Real-World Example: A database connection pool where only one connection pool object exists
throughout the application.
Java Example:
private DatabaseConnection() {}
if (instance == null) {
return instance;
Description: Defines an interface for creating objects, but allows subclasses to alter the type of
objects that will be created.
Real-World Example: A document editor that can create different types of documents (e.g.,
Word, PDF) based on user selection.
interface Document {
void open();
doc.open();
}
}
Description: Provides an interface for creating families of related or dependent objects without
specifying their concrete classes.
Real-World Example: A GUI toolkit that can create buttons and checkboxes for different
operating systems (e.g., Windows, Mac).
// Abstract products
interface Button {
void paint();
interface Checkbox {
void paint();
// Abstract factory
interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
// Concrete factories
}
public Checkbox createCheckbox() {
Description: Separates the construction of a complex object from its representation so that the
same construction process can create different representations.
Real-World Example: Building a car with different options (e.g., color, engine type) using a car
builder.
class Car {
this.color = color;
}
public void setEngineType(String engineType) {
this.engineType = engineType;
@Override
class CarBuilder {
public CarBuilder() {
car.setColor(color);
return this;
car.setEngineType(engineType);
return this;
return car;
}
2. Structural Patterns
Description: Allows an interface to be used in a way that it was not originally intended by
adapting it to a different interface.
Real-World Example: A power adapter that allows devices from different countries to be used
with different electrical outlets.
// Target interface
interface Voltage {
void connect();
// Adaptee
class OldVoltage {
// Adapter
this.oldVoltage = oldVoltage;
}
public void connect() {
oldVoltage.connectToOldSocket();
Description: Separates an abstraction from its implementation so that the two can vary
independently.
Real-World Example: A remote control that can work with different types of devices (e.g., TV,
stereo).
Java Example:
// Abstraction
this.device = device;
// RefinedAbstraction
super(device);
// Implementor
interface Device {
void turnOn();
// ConcreteImplementor
Real-World Example: A file system where both files and directories are treated as file system
objects.
import java.util.ArrayList;
import java.util.List;
// Component
interface FileSystemComponent {
void showDetails();
// Leaf
this.name = name;
// Composite
this.name = name;
children.add(component);
}
component.showDetails();
Description: Adds new functionality to an object dynamically without altering its structure.
Real-World Example: Adding extra features to a coffee, such as milk or sugar, in a coffee shop.
// Component
interface Coffee {
String getDescription();
double cost();
// ConcreteComponent
return 5.0;
}
}
// Decorator
this.coffee = coffee;
return coffee.getDescription();
return coffee.cost();
// ConcreteDecorator
super(coffee);
}
public double cost() {
3. Behavioral Patterns
Description: Defines a family of algorithms, encapsulates each one, and makes them
interchangeable.
Real-World Example: A payment system that can switch between different payment methods
(e.g., credit card, PayPal).
Java Example:
// Strategy
interface PaymentStrategy {
// ConcreteStrategy
// ConcreteStrategy
// Context
class PaymentContext {
this.strategy = strategy;
strategy.pay(amount);
Description: Defines a one-to-many dependency between objects so that when one object
changes state, all its dependents are notified and updated automatically.
Real-World Example: A news agency that notifies all subscribers when a new article is
published.
Java Example:
import java.util.ArrayList;
import java.util.List;
// Observer
interface Observer {
// ConcreteObserver
this.name = name;
// Subject
class NewsAgency {
observers.add(observer);
observers.remove(observer);
notifyObservers();
observer.update(latestNews);
Real-World Example: A remote control that can execute different commands (e.g., turn on
lights, change TV channel).
Java Example:
// Command
interface Command {
void execute();
// ConcreteCommand
this.light = light;
}
light.turnOn();
// Receiver
class Light {
System.out.println("Light is on.");
// Invoker
class RemoteControl {
this.command = command;
command.execute();
Real-World Example: A document editor with states like "Editing," "Read-Only," and
"Locked."
Java Example:
// State
interface State {
void handleRequest();
// ConcreteState
// ConcreteState
// Context
class Document {
state.handleRequest();
Description: Defines the skeleton of an algorithm in the superclass but lets subclasses override
specific steps of the algorithm without changing its structure.
Real-World Example: A recipe with fixed steps where specific ingredients or cooking times can
be customized.
Java Example:
boilWater();
brew();
pourInCup();
addCondiments();
System.out.println("Boiling water.");
}
private void pourInCup() {
System.out.println("Adding lemon.");
Description: Provides a way to access the elements of an aggregate object sequentially without
exposing its underlying representation.
Real-World Example: An iterator over a playlist of songs where you can move through each
song one by one.
Java Example:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
// Aggregate
interface Aggregate {
Iterator<String> createIterator();
// ConcreteAggregate
songs.add(song);
return songs.iterator();
Real-World Example: A flight control tower managing interactions between multiple planes.
Java Example:
// Mediator
interface Mediator {
// ConcreteMediator
this.colleagueA = colleagueA;
this.colleagueB = colleagueB;
if (colleague == colleagueA) {
colleagueB.receiveMessage(message);
} else {
colleagueA.receiveMessage(message);
// Colleague
this.mediator = mediator;
// ConcreteColleagueA
super(mediator);
mediator.sendMessage(message, this);
// ConcreteColleagueB
super(mediator);
Real-World Example: A help desk system where requests are passed from a junior support
agent to a senior one if the issue is not resolved.
Java Example:
this.nextHandler = handler;
if (request.equals("A")) {
nextHandler.handleRequest(request);
}
class ConcreteHandlerB extends Handler {
if (request.equals("B")) {
nextHandler.handleRequest(request);
Description: Allows adding new operations to objects without modifying the objects themselves.
Real-World Example: A tax calculation system that applies different tax rules to different types
of items (e.g., books, electronics).
Java Example:
// Visitor
interface Visitor {
// Element
interface Element {
// ConcreteElement
visitor.visit(this);
// ConcreteElement
visitor.visit(this);
// ConcreteVisitor