OOP Design Patterns
Creational Patterns
Section titled “Creational Patterns”1. Singleton
Section titled “1. Singleton”|
Problem: Ensure only one instance exists, global access. Use Case: Config manager, logging service, DB Connection |
classDiagram
class Logger {
-static Logger instance
-Logger()
+getInstance()
+log()
}
|
Code Sample
Section titled “Code Sample”class Logger { private static Logger instance; private Logger() {} public static Logger getInstance() { if (instance == null) instance = new Logger(); return instance; } public void log(String msg) { System.out.println(msg); }}2. Factory Method
Section titled “2. Factory Method”|
Problem: Create objects without exposing instantiation logic. Use Case: Payment processor selection. |
classDiagram
class Payment {
<
|
Code Sample
Section titled “Code Sample”interface Payment { void pay(double amount);}class PayPal implements Payment { public void pay(double a){ System.out.println("PayPal "+a); }}
class Stripe implements Payment { public void pay(double a){ System.out.println("Stripe "+a); }}
class PaymentFactory { static Payment getPayment(String type) { return type.equals("paypal") ? new PayPal() : new Stripe(); }}3. Abstract Factory
Section titled “3. Abstract Factory”|
Problem: Provide an interface for creating families of related objects. Use Case: GUI toolkit (Windows vs Mac). |
classDiagram
class GUIFactory {
<
|
Code Sample
Section titled “Code Sample”interface Button { void render(); }
class WinButton implements Button { public void render(){ System.out.println("Win Button"); }}
class MacButton implements Button { public void render(){ System.out.println("Mac Button"); }}
interface GUIFactory { Button createButton(); }
class WinFactory implements GUIFactory { public Button createButton(){ return new WinButton(); }}
class MacFactory implements GUIFactory { public Button createButton(){ return new MacButton(); }}Structural Patterns
Section titled “Structural Patterns”4. Adapter
Section titled “4. Adapter”|
Problem: Convert one interface into another. Use Case: Old payment library → New checkout system. |
classDiagram
class LegacyPayment {
+makePayment()
}
class ModernPayment {
<
|
Code Sample
Section titled “Code Sample”class LegacyPayment { void makePayment(){ System.out.println("Legacy Paid"); }}
interface ModernPayment { void pay();}
class Adapter implements ModernPayment { private LegacyPayment legacy = new LegacyPayment(); public void pay(){ legacy.makePayment(); }}5. Decorator
Section titled “5. Decorator”|
Problem: Add responsibilities dynamically without altering code. Use Case: Logging, compression, encryption for data streams. |
classDiagram
class Notifier {
<
|
Code Sample
Section titled “Code Sample”interface Notifier { void send(String msg);}class EmailNotifier implements Notifier { public void send(String m){ System.out.println("Email: "+m); }}
class SMSDecorator implements Notifier { private Notifier wrap;
SMSDecorator(Notifier n){ wrap=n; }
public void send(String m) { wrap.send(m); System.out.println("SMS: "+m); }}6. Facade
Section titled “6. Facade”|
Problem: Simplify a complex subsystem. Use Case: Video conversion API. |
classDiagram
class VideoFacade {
+convert()
}
class CodecLoader
class VideoCompressor
VideoFacade --> CodecLoader
VideoFacade --> VideoCompressor
|
Code Sample
Section titled “Code Sample”class CodecLoader { void load(){ System.out.println("Codec Loaded"); }}
class VideoCompressor { void compress(){ System.out.println("Compressed"); }}
class VideoFacade { private CodecLoader loader = new CodecLoader(); private VideoCompressor comp = new VideoCompressor(); void convert(){ loader.load(); comp.compress(); }}Behavioral Patterns
Section titled “Behavioral Patterns”7. Observer
Section titled “7. Observer”|
Problem: One-to-many dependency. Use Case: Order placed → notify email, update inventory. |
classDiagram
class Observer {
<
|
Code Sample
Section titled “Code Sample”interface Observer { void update(String msg);}
class EmailObserver implements Observer { public void update(String m){ System.out.println("Email: "+m); }}
class Order { List<Observer> observers = new ArrayList<>(); void addObserver(Observer o){ observers.add(o); } void place(){ for(Observer o: observers) o.update("Order placed"); }}8. Strategy
Section titled “8. Strategy”|
Problem: Choose algorithm at runtime. Use Case: Different shipping cost strategies. |
classDiagram
class Shipping {
<
|
Code Sample
Section titled “Code Sample”interface Shipping { double cost(double w);}
class Air implements Shipping { public double cost(double w){ return w*10; }}
class Sea implements Shipping { public double cost(double w){ return w*5; }}
class Cart { Shipping s; Cart(Shipping s){ this.s=s; } double calc(double w){ return s.cost(w); }}9. Command
Section titled “9. Command”|
Problem: Encapsulate requests as objects. Use Case: Undo/redo in editors. |
classDiagram
class Command {
<
|
Code Sample
Section titled “Code Sample”interface Command { void execute();}
class LightOn implements Command { public void execute(){ System.out.println("Light ON"); }}
class Remote { Command cmd; void setCommand(Command c){ cmd=c; } void press(){ cmd.execute(); }}10. Template Method
Section titled “10. Template Method”|
Problem: Define algorithm skeleton, let subclasses fill details. Use Case: Report generation. |
classDiagram
class Report {
+generate()
+header()
+body()*
+footer()
}
class SalesReport
Report <|-- SalesReport
|
Code Sample
Section titled “Code Sample”abstract class Report {
final void generate(){ header(); body(); footer(); }
void header(){ System.out.println("Header"); } abstract void body();
void footer(){ System.out.println("Footer"); }}class SalesReport extends Report { void body(){ System.out.println("Sales Data"); }}