1.
Singleton Pattern
Definition: Ensures only one instance of a class is created and provides a global point of access to it.
Analogy: Imagine a print spooler - only one print manager handles all jobs.
Code Example:
class PrinterSpooler {
private static PrinterSpooler instance = new PrinterSpooler();
private PrinterSpooler() { System.out.println("Spooler Initialized."); }
public static PrinterSpooler getInstance() { return instance; }
public void print(String doc) { System.out.println("Printing: " + doc); }
}
When to Use: Logging, Configuration Manager, Database connection pool
2. Factory Method Pattern
Definition: Provides an interface for creating objects but lets subclasses alter the type of created object.
Analogy: Pizza store decides to return Veg or Chicken pizza.
Code Example:
interface Pizza { void prepare(); }
class VegPizza implements Pizza {
public void prepare() { System.out.println("Preparing Veg Pizza"); }
}
class ChickenPizza implements Pizza {
public void prepare() { System.out.println("Preparing Chicken Pizza"); }
}
class PizzaFactory {
public Pizza getPizza(String type) {
if (type.equalsIgnoreCase("veg")) return new VegPizza();
else if (type.equalsIgnoreCase("chicken")) return new ChickenPizza();
return null;
}
}
When to Use: When object creation logic needs to be hidden from the client.
3. Builder Pattern
Definition: Builds complex objects step-by-step using a builder class.
Analogy: Making a burger by selecting bun, patty, sauce step-by-step.
Code Example:
class Burger {
private String bun, patty, sauce;
private Burger(BurgerBuilder b) {
this.bun = b.bun; this.patty = b.patty; this.sauce = b.sauce;
}
public static class BurgerBuilder {
String bun, patty, sauce;
public BurgerBuilder setBun(String b) { bun = b; return this; }
public BurgerBuilder setPatty(String p) { patty = p; return this; }
public BurgerBuilder setSauce(String s) { sauce = s; return this; }
public Burger build() { return new Burger(this); }
}
}
When to Use: When object has many optional fields or step-by-step construction is needed.
4. Adapter Pattern
Definition: Allows incompatible interfaces to work together.
Analogy: Using USB-C to Micro-USB adapter for charging.
Code Example:
interface MediaPlayer { void play(String type, String file); }
class VLCPlayer {
void playVLC(String file) { System.out.println("Playing VLC: " + file); }
}
class MediaAdapter implements MediaPlayer {
VLCPlayer vlc = new VLCPlayer();
public void play(String type, String file) {
if (type.equalsIgnoreCase("vlc")) vlc.playVLC(file);
}
}
When to Use: When integrating legacy or third-party code with different interfaces.
5. Decorator Pattern
Definition: Dynamically adds behavior to an object without altering its structure.
Analogy: Adding milk or sugar to plain coffee.
Code Example:
interface Coffee {
String getDescription(); int getCost();
}
class SimpleCoffee implements Coffee {
public String getDescription() { return "Simple Coffee"; }
public int getCost() { return 5; }
}
class MilkDecorator implements Coffee {
Coffee c; MilkDecorator(Coffee c) { this.c = c; }
public String getDescription() { return c.getDescription() + ", Milk"; }
public int getCost() { return c.getCost() + 2; }
}
When to Use: To add features at runtime (I/O streams, UI components).
6. Facade Pattern
Definition: Provides a simplified interface to a complex system of classes.
Analogy: Movie booking website interacts with payment, cinema, seats behind scenes.
Code Example:
class Lights { void dim() { System.out.println("Lights dimmed."); } }
class Projector { void on() { System.out.println("Projector on."); } }
class SoundSystem { void play() { System.out.println("Sound playing."); } }
class HomeTheaterFacade {
Lights l = new Lights(); Projector p = new Projector(); SoundSystem s = new SoundSystem();
void watchMovie() {
l.dim(); p.on(); s.play();
System.out.println("Movie started.");
}
}
When to Use: When simplifying complex APIs or libraries.
7. Observer Pattern
Definition: One-to-many dependency where one change notifies all observers.
Analogy: YouTube notifies all subscribers when a creator uploads.
Code Example:
interface Subscriber { void update(String video); }
class User implements Subscriber {
String name; User(String name) { this.name = name; }
public void update(String v) {
System.out.println(name + " notified: " + v);
}
}
class Channel {
List<Subscriber> subs = new ArrayList<>();
void subscribe(Subscriber s) { subs.add(s); }
void upload(String v) {
for (Subscriber s : subs) s.update(v);
}
}
When to Use: Event-driven systems (UI, real-time apps).
8. Strategy Pattern
Definition: Defines a family of algorithms, encapsulates each, and makes them interchangeable at runtime.
Analogy: Choosing payment strategy: UPI, Card, PayPal.
Code Example:
interface PaymentStrategy { void pay(int amount); }
class CreditCardPayment implements PaymentStrategy {
public void pay(int amt) { System.out.println("Paid by Card: " + amt); }
}
class UPIPayment implements PaymentStrategy {
public void pay(int amt) { System.out.println("Paid by UPI: " + amt); }
}
class PaymentContext {
PaymentStrategy strategy;
void setStrategy(PaymentStrategy s) { strategy = s; }
void pay(int amt) { strategy.pay(amt); }
}
When to Use: When multiple algorithms are available for a task.