1. The Hook (The "Byte-Sized" Intro)
- In a Nutshell: Design patterns are proven solutions to common problems.
- Two key patterns leverage inheritance: Template Method (define algorithm skeleton in parent, let children fill in details) and Factory Method (let subclasses decide which class to instantiate). These patterns are used extensively in frameworks like Spring, Android, and JUnit.
Think of cooking recipes. A recipe (Template Method) says "1. Prep ingredients, 2. Cook, 3. Serve" but you customize what you prep/cook. That's a template pattern!
2. Conceptual Clarity (The "Simple" Tier)
💡 The Analogy: The Assembly Line
Template Method: The factory has a fixed assembly process (template), but each car model customizes specific steps (e.g., paint color, engine type).
Factory Method: The production line decides which specific car model to build based on the order.
3. Technical Mastery (The "Deep Dive")
Pattern 1: Template Method
Purpose: Define the skeleton of an algorithm, deferring some steps to subclasses.
abstract class DataProcessor {
// Template method (final to prevent override)
public final void process() {
readData();
processData(); // Hook method
writeData();
}
void readData() {
System.out.println("Reading data...");
}
// Abstract: subclasses must implement
abstract void processData();
void writeData() {
System.out.println("Writing data...");
}
}
class CSVProcessor extends DataProcessor {
@Override
void processData() {
System.out.println("Processing CSV data");
}
}
class JSONProcessor extends DataProcessor {
@Override
void processData() {
System.out.println("Processing JSON data");
}
}
// Usage
public class Main {
public static void main(String[] args) {
DataProcessor csv = new CSVProcessor();
csv.process(); // Calls template: read → process CSV → write
DataProcessor json = new JSONProcessor();
json.process(); // Calls template: read → process JSON → write
}
}Pattern 2: Factory Method
Purpose: Define an interface for creating objects, but let subclasses decide which class to instantiate.
// Product interface
interface Vehicle {
void drive();
}
class Car implements Vehicle {
public void drive() {
System.out.println("Driving a car");
}
}
class Bike implements Vehicle {
public void drive() {
System.out.println("Riding a bike");
}
}
// Creator (Factory)
abstract class VehicleFactory {
// Template method using factory method
public void deliverVehicle() {
Vehicle v = createVehicle(); // Factory method
v.drive();
}
// Factory method (subclasses override)
abstract Vehicle createVehicle();
}
class CarFactory extends VehicleFactory {
@Override
Vehicle createVehicle() {
return new Car();
}
}
class BikeFactory extends VehicleFactory {
@Override
Vehicle createVehicle() {
return new Bike();
}
}
// Usage
public class Main {
public static void main(String[] args) {
VehicleFactory factory = new CarFactory();
factory.deliverVehicle(); // Creates and delivers Car
factory = new BikeFactory();
factory.deliverVehicle(); // Creates and delivers Bike
}
}4. Interactive & Applied Code
// Real-World Example: Game Character
abstract class GameCharacter {
// Template Method
public final void performAttack() {
prepareAttack();
executeAttack(); // Hook
cooldown();
}
void prepareAttack() {
System.out.println("Character preparing...");
}
abstract void executeAttack(); // Customization point
void cooldown() {
System.out.println("Attack cooldown...");
}
}
class Warrior extends GameCharacter {
@Override
void executeAttack() {
System.out.println("⚔️ Sword slash!");
}
}
class Mage extends GameCharacter {
@Override
void executeAttack() {
System.out.println("🔮 Fireball cast!");
}
}
public class Main {
public static void main(String[] args) {
GameCharacter player = new Warrior();
player.performAttack();
player = new Mage();
player.performAttack();
}
}5. The Comparison & Decision Layer
Versus Table
| Pattern | Purpose | When to Use |
|---|---|---|
| Template Method | Define algorithm skeleton | Fixed workflow, variable steps |
| Factory Method | Delegate object creation | Don't know exact class needed |
6. The "Interview Corner" (The Edge)
The "Killer" Interview Question:
"Explain Template Method pattern with a real example."
Answer: Template Method defines an algorithm's structure in a superclass, allowing subclasses to customize specific steps without changing the overall flow. Example: AbstractList.add() in Java Collections—the algorithm is defined, but specific storage mechanisms vary (ArrayList vs LinkedList).
Real-World Usage
- JUnit:
TestCase.runTest()(template method) - Servlet:
HttpServlet.service()callsdoGet(),doPost()(hook methods) - Spring:
JdbcTemplate(template method pattern)
Pro-Tip: Mark template methods as final to prevent subclasses from breaking the algorithm flow!
public final void templateMethod() {
step1();
step2(); // Subclass customizes this
step3();
}