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() { [Link]("Spooler Initialized."); }
public static PrinterSpooler getInstance() { return instance; }
public void print(String doc) { [Link]("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() { [Link]("Preparing Veg Pizza"); }
}
class ChickenPizza implements Pizza {
public void prepare() { [Link]("Preparing Chicken Pizza"); }
}
class PizzaFactory {
public Pizza getPizza(String type) {
if ([Link]("veg")) return new VegPizza();
else if ([Link]("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) {
[Link] = [Link]; [Link] = [Link]; [Link] = [Link];
}
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) { [Link]("Playing VLC: " + file); }
}
class MediaAdapter implements MediaPlayer {
VLCPlayer vlc = new VLCPlayer();
public void play(String type, String file) {
if ([Link]("vlc")) [Link](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 [Link]() + ", Milk"; }
public int getCost() { return [Link]() + 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() { [Link]("Lights dimmed."); } }
class Projector { void on() { [Link]("Projector on."); } }
class SoundSystem { void play() { [Link]("Sound playing."); } }
class HomeTheaterFacade {
Lights l = new Lights(); Projector p = new Projector(); SoundSystem s = new SoundSystem();
void watchMovie() {
[Link](); [Link](); [Link]();
[Link]("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) { [Link] = name; }
public void update(String v) {
[Link](name + " notified: " + v);
}
}
class Channel {
List<Subscriber> subs = new ArrayList<>();
void subscribe(Subscriber s) { [Link](s); }
void upload(String v) {
for (Subscriber s : subs) [Link](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) { [Link]("Paid by Card: " + amt); }
}
class UPIPayment implements PaymentStrategy {
public void pay(int amt) { [Link]("Paid by UPI: " + amt); }
}
class PaymentContext {
PaymentStrategy strategy;
void setStrategy(PaymentStrategy s) { strategy = s; }
void pay(int amt) { [Link](amt); }
}
When to Use: When multiple algorithms are available for a task.