Bird
Raised Fist0

Template Method Pattern - Defining Algorithm Skeleton, Subclasses Fill In Steps

LLDeasyInterview freq: high
Choose your preparation mode4 modes available
▶
Class Trace
Step 1/4
AbstractAlgorithm class

AbstractAlgorithm defines the templateMethod() as the algorithm skeleton with synchronized step1() and a hook() method.

🎯 Tests whether candidate understands abstract class is used to hold shared state and behavior, which interfaces cannot hold in Java, and why step1() is synchronized to ensure thread safety.
public abstract class AbstractAlgorithm {
    public final void templateMethod() {
        step1();
        step2();
        hook();
    }
    protected synchronized void step1() {
        // default implementation
    }
    protected abstract void step2();
    protected void hook() {
        // optional hook method
    }
}
ConcreteAlgorithmA subclass

ConcreteAlgorithmA overrides step2() to provide specific behavior while inheriting the templateMethod skeleton.

🎯 Tests whether candidate knows realization of abstract methods in subclasses enforces Liskov Substitution Principle and Open-Closed Principle by extending without modifying AbstractAlgorithm.
public class ConcreteAlgorithmA extends AbstractAlgorithm {
    @Override
    protected void step2() {
        // specific implementation for A
    }
}
ConcreteAlgorithmB subclass

ConcreteAlgorithmB also overrides step2() differently, showing polymorphic extension of the algorithm skeleton.

🎯 Tests whether candidate understands multiple concrete subclasses can provide different behaviors while sharing the same algorithm skeleton, enforcing OCP.
public class ConcreteAlgorithmB extends AbstractAlgorithm {
    @Override
    protected void step2() {
        // specific implementation for B
    }
}
Client association with AbstractAlgorithm

Client holds a reference to AbstractAlgorithm and calls templateMethod(), demonstrating dependency inversion and runtime polymorphism.

🎯 Tests whether candidate knows association means Client does not own AbstractAlgorithm lifecycle and can switch implementations at runtime, enforcing Dependency Inversion Principle.
public class Client {
    private AbstractAlgorithm algorithm;
    public Client(AbstractAlgorithm algorithm) {
        this.algorithm = algorithm;
    }
    public void execute() {
        algorithm.templateMethod();
    }
}
📐
Class Diagram
Class Diagram
       +---------------------+
       | <<Abstract>>        |
       | AbstractAlgorithm   |
       +---------------------+
       | - templateMethod()  |
       | - step1() [sync]    |
       | - step2()           |
       | - hook()            |
       +---------------------+
                │ extends
       +---------------------+
       | ConcreteAlgorithmA  |
       +---------------------+
       | - step2()           |
       +---------------------+
                │ extends
       +---------------------+
       | ConcreteAlgorithmB  |
       +---------------------+
       | - step2()           |
       +---------------------+
                │
                │ association
       +---------------------+
       | Client              |
       +---------------------+
       | - algorithm: AbstractAlg |
       | + execute()         |
       +---------------------+

This diagram illustrates the Template Method pattern in Java using an abstract class AbstractAlgorithm that defines the algorithm skeleton via templateMethod(). The synchronized modifier on step1() ensures thread-safe execution of that step, a Java-specific concurrency control. ConcreteAlgorithmA and ConcreteAlgorithmB realize the abstract step2() method, demonstrating polymorphic extension without modifying the base class, enforcing the Open-Closed Principle. The hook() method in AbstractAlgorithm provides an optional extension point, a classic Hook Method pattern. The Client class holds an association to AbstractAlgorithm, allowing runtime substitution of concrete algorithms, enforcing Dependency Inversion Principle. This design leverages Java's abstract classes for shared state and behavior, synchronized methods for concurrency safety, and runtime polymorphism for extensibility.

Primary Focus

✓ Abstract class vs interface + Template Method algorithm skeleton + Hook method usage

Practice

(1/5)
1. In the Social Media Profile System, the User class has a private constructor and a static synchronized getInstance() method to manage user sessions. Which design pattern is applied here and why is this the correct choice?
easy
A. Singleton Pattern, ensuring only one instance manages user sessions globally.
B. Factory Pattern, because it creates objects without exposing instantiation logic.
C. Builder Pattern, to construct complex User objects step-by-step.
D. Prototype Pattern, to clone existing User instances efficiently.

Solution

  1. Step 1: Identify the pattern from constructor and method

    The private constructor prevents external instantiation, and the static synchronized getInstance() method controls instance creation, which matches Singleton pattern characteristics.
  2. Step 2: Why Singleton fits user session management

    Singleton ensures a single global instance manages user sessions, avoiding multiple conflicting session managers.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Private constructor + static synchronized getInstance() -> Singleton [check]
Hint: Private constructor + static getInstance() -> Singleton [check]
Common Mistakes:
2. In the Stack Overflow voting system, if the castVote() method is not synchronized, which exact sequence of thread interleaving causes a double vote count for the same user on a question?
medium
A. Thread 1 reads vote count, Thread 2 reads vote count, both increment and write back simultaneously
B. Thread 1 checks if user has voted -> false, context switch; Thread 2 checks if user has voted -> false; both proceed to cast vote
C. Thread 1 updates vote count, Thread 2 waits; Thread 1 finishes, Thread 2 updates vote count again
D. Thread 1 and Thread 2 both block on the same lock, causing deadlock

Solution

  1. Step 1: Identify the check-then-act race condition

    The critical issue is the check if the user has already voted. Without synchronization, both threads see no vote recorded and proceed.
  2. Step 2: Trace exact interleaving causing double vote

    Thread 1 checks voted -> false, context switch; Thread 2 checks voted -> false; both cast votes, causing double count.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Check-then-act gap without sync -> double vote [check]
Hint: Check-then-act gap -> double vote without sync [check]
Common Mistakes:
3. In a parking lot system, the parkVehicle() method checks if a spot is available and then marks it occupied. Without synchronized, which exact thread interleaving causes double-booking?
medium
A. Thread 1 reads spot as occupied, Thread 2 reads spot as available, both park vehicles.
B. Thread 1 marks spot occupied, Thread 2 waits and then parks after spot is freed.
C. Thread 1 checks isAvailable() -> true, context switch before marking occupied; Thread 2 checks isAvailable() -> true, both mark occupied.
D. Thread 1 and Thread 2 both wait on a lock, preventing double-booking.

Solution

  1. Step 1: Identify check-then-act race condition

    Without synchronization, Thread 1 reads spot as available but is preempted before marking it occupied. Thread 2 also reads spot as available and proceeds to mark it occupied.
  2. Step 2: Understand resulting double-booking

    Both threads believe the spot is free and park vehicles, causing double-booking due to the gap between check and update.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Check-then-act gap without synchronization -> double-booking [check]
Hint: Check-then-act gap -> both see available -> double-book [check]
Common Mistakes:
4. In a parking lot system, if parkVehicle() is not synchronized, which exact sequence of Thread 1 and Thread 2 causes double-booking of the same spot?
medium
A. Thread 1 parks vehicle, Thread 2 waits until Thread 1 finishes, then parks another vehicle.
B. Thread 1 and Thread 2 both crash due to simultaneous access.
C. Thread 1 checks spot availability -> true, context switch; Thread 2 checks spot availability -> true; both park simultaneously.
D. Thread 1 parks vehicle, Thread 2 reads spot as occupied and waits.

Solution

  1. Step 1: Identify the check-then-act race condition

    Without synchronization, Thread 1 reads spot as available but before marking it occupied, context switches to Thread 2 which also reads it as available.
  2. Step 2: Both threads proceed to park, causing double-booking

    Because the state update is not atomic, both threads park vehicles in the same spot simultaneously.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Unsynchronized check-then-act -> double-booking race [check]
Hint: Check-then-act gap causes double-booking without synchronization [check]
Common Mistakes:
5. To support ElectricCar players who require ChargingSpot in the Tic-Tac-Toe game parking analogy, what is the minimum design change that respects extensibility without modifying existing classes?
hard
A. Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType, create ElectricCar subclass, and update SpotCompatibility.COMPATIBILITY_MAP accordingly.
B. Modify existing Vehicle and Spot classes to include electric-specific logic and fields.
C. Create a new ElectricCar class with embedded charging logic and modify the parking manager to handle it.
D. Use a flag in the Vehicle class to indicate electric type and add conditional logic in parking spots.

Solution

  1. Step 1: Identify extensibility requirements

    Adding ElectricCar and ChargingSpot should not require modifying existing classes to avoid violating OCP and creating class explosion.
  2. Step 2: Why Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType, create ElectricCar subclass, and update SpotCompatibility.COMPATIBILITY_MAP accordingly. is minimal and extensible

    Adding new enum values and a subclass keeps existing classes unchanged. Updating the compatibility map centralizes compatibility logic without scattering changes.
  3. Step 3: Why other options violate extensibility

    Options B, C, and D modify existing classes or add conditional logic, increasing coupling and violating OCP.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    New enums + subclass + compatibility map update -> minimal, extensible [check]
Hint: New enums + subclass + map update -> extend without modify [check]
Common Mistakes:
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard