Modern Design Patterns in Java: Principles and Practice
Standard Solutions to Common Problems
Design patterns provide a shared vocabulary and a set of proven templates for solving recurring design challenges. This guide focuses on the “Big Four” patterns used in modern Java development.
Core Concepts
1. Singleton
Ensures a class has only one instance and provides a global point of access to it.
- Modern Java: Use an
enumfor the safest, easiest Singleton.
2. Strategy
Defines a family of algorithms, encapsulates each one, and makes them interchangeable.
- Java Tip: Use Functional Interfaces and Lambdas to implement lightweight strategies.
3. Observer
Defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified automatically.
4. Factory
Provides an interface for creating objects in a superclass but allows subclasses to alter the type of objects that will be created.
Practice Exercise: The Strategy Pattern for Payments
We will build a payment processing system where the user can choose between Credit Card and PayPal at runtime.
Step 1: The Strategy Interface
@FunctionalInterface
public interface PaymentStrategy {
void pay(int amount);
}
Step 2: Concrete Implementations
public class CreditCardStrategy implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using Credit Card.");
}
}
public class PaypalStrategy implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using PayPal.");
}
}
Step 3: Usage
public class ShoppingCart {
public void processOrder(int total, PaymentStrategy paymentMethod) {
paymentMethod.pay(total);
}
}
// Client Code
cart.processOrder(100, new CreditCardStrategy());
cart.processOrder(50, amount -> System.out.println("Apple Pay: " + amount)); // Using Lambda!
Why This Works
- Open/Closed Principle: You can add a new payment method (e.g., Bitcoin) by creating a new
PaymentStrategyimplementation without changing theShoppingCartclass. - Encapsulation: The logic for how to pay is hidden from the
ShoppingCart, which only cares that it can pay.
Summary
Design patterns are tools, not targets. Don’t over-engineer your code by forcing patterns where they don’t fit. But when complexity rises, patterns like Strategy or Factory provide a clean, industry-standard way to manage it.