Chaturmind
LearnDSASystem DesignInterview PrepDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth
  • Java Interview Prep

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Java Interview Prep: 5–8 Years

Advanced Core Java

  • Advanced OOP & Design Scenarios — Interview Questions
  • Advanced Concurrency, Collections & Memory — Interview Questions
  • Modern Java Language Features & Annotations — Interview Questions
  • Class Loading, Reflection, Serialization & Idioms — Interview Questions

Java Design Patterns in Depth

  • Design Patterns Overview & Singleton — Interview Questions
  • Factory & Abstract Factory Patterns — Interview Questions
  • Builder & Prototype Patterns — Interview Questions
  • Adapter & Bridge Patterns — Interview Questions
  • Composite & Decorator Patterns — Interview Questions
  • Facade & Proxy Patterns — Interview Questions
  • Chain of Responsibility & Observer Patterns — Interview Questions
  • Strategy & Template Method Patterns — Interview Questions
  • Command Pattern — Interview Questions

Advanced Spring Boot

  • Logging, Configuration & Actuator (Advanced) — Interview Questions
  • Transactions, Multiple Datasources & Query Tuning — Interview Questions
  • Validation & REST API Design (Advanced) — Interview Questions
  • Reactive, Async & Scheduling in Spring Boot — Interview Questions
  • Deployment, High Availability, Scaling & Caching — Interview Questions
Chaturmind
← Java Interview Prep: 5–8 Years

Advanced Core Java

  • Advanced OOP & Design Scenarios — Interview Questions
  • Advanced Concurrency, Collections & Memory — Interview Questions
  • Modern Java Language Features & Annotations — Interview Questions
  • Class Loading, Reflection, Serialization & Idioms — Interview Questions

Java Design Patterns in Depth

  • Design Patterns Overview & Singleton — Interview Questions
  • Factory & Abstract Factory Patterns — Interview Questions
  • Builder & Prototype Patterns — Interview Questions
  • Adapter & Bridge Patterns — Interview Questions
  • Composite & Decorator Patterns — Interview Questions
  • Facade & Proxy Patterns — Interview Questions
  • Chain of Responsibility & Observer Patterns — Interview Questions
  • Strategy & Template Method Patterns — Interview Questions
  • Command Pattern — Interview Questions

Advanced Spring Boot

  • Logging, Configuration & Actuator (Advanced) — Interview Questions
  • Transactions, Multiple Datasources & Query Tuning — Interview Questions
  • Validation & REST API Design (Advanced) — Interview Questions
  • Reactive, Async & Scheduling in Spring Boot — Interview Questions
  • Deployment, High Availability, Scaling & Caching — Interview Questions
HomeLearnJava Interview PrepJava Interview Prep: 5–8 YearsJava Design Patterns in Depth
✓ FreeAdvanced· 9 min read

Strategy & Template Method Patterns — Interview Questions

Strategy — interchangeable algorithms selected at runtime, Java and Spring implementations (map-of-beans, lambdas), benefits, the payment-method example — and Template Method — a fixed algorithm skeleton with overridable steps, implementation with final template methods and hooks, examples (Spring's JdbcTemplate, AbstractController-style bases), limitations, and Strategy vs Template Method.

Published September 25, 2026


How to use this lesson

Strategy and Template Method solve the same problem, varying part of an algorithm, in opposite ways:

  • Strategy uses composition: the varying part is an object you pass in.
  • Template Method uses inheritance: the varying part is a method a subclass overrides.

Senior interviewers expect you to compare them. They also expect you to know that since Java 8, many strategies are just lambdas, and that Spring's *Template classes are mostly callback-based strategies, despite the name.

Q1. What is the Strategy pattern for?

Short answer: Strategy defines a family of algorithms, encapsulates each one, and makes them interchangeable, so the algorithm can vary independently of the client that uses it. It's typically used for payment methods, pricing or discount rules, sorting and comparison, compression, routing or shipping-cost calculations, and retry or backoff policies.

Learn it in depth → Strategy Pattern

Q2. What is the Template Method pattern for?

Short answer: Template Method defines the skeleton of an algorithm in a base-class method. Subclasses redefine certain steps without changing the overall structure. It's typically used for data importers (read, parse, validate, save) where only the parsing differs between CSV, XML and JSON, report generation, and framework lifecycle hooks.

Learn it in depth → Template Method

Q3. What is the Strategy pattern, and when would you use it?

Short answer: Use it when there are several ways to do one task, the choice is made at runtime (by configuration, user input or data), and you want to avoid a growing if/else or switch over types in the client. Each variant becomes its own class, or a lambda, behind a common interface.

Key points to cover:

  • Signs you need it:
    • The same switch (type) appears in several places.
    • Adding a variant means editing existing, tested code.
    • The variants need separate unit tests.

Q4. How does Strategy differ from Template Method?

Short answer:

StrategyTemplate Method
MechanismComposition: the context holds a strategy objectInheritance: a subclass overrides steps
What variesThe whole algorithmSome steps within a fixed algorithm
When it's chosenAt runtime, and it can be swappedAt compile time, fixed by the subclass
CouplingLoose: the context knows only the interfaceTight: subclasses depend on the base-class internals
Java 8+Often just a lambdaNeeds a class hierarchy

Prefer Strategy (composition) by default. Use Template Method when the ordering and invariants must be enforced by a base class, and the variation points are small.

Common trap: the source's answer to "how does Template Method differ from Strategy?" (DP-094) only describes Template Method. Always state both sides, and the composition-vs-inheritance difference.

Q5. How would you implement the Strategy pattern in Java?

Short answer:

  1. Define the strategy interface.
  2. Write one implementation per algorithm.
  3. Have the context depend on the interface.
  4. Choose the strategy at runtime.

In Spring, inject all implementations as a map, and select by key. That removes the switch entirely.

public interface PaymentStrategy {
    PaymentMethod method();
    PaymentResult pay(Order order, PaymentDetails details);
}

@Component class CardPayment implements PaymentStrategy {
    public PaymentMethod method() { return PaymentMethod.CARD; }
    public PaymentResult pay(Order o, PaymentDetails d) { /* card gateway */ return PaymentResult.ok(); }
}
@Component class UpiPayment implements PaymentStrategy {
    public PaymentMethod method() { return PaymentMethod.UPI; }
    public PaymentResult pay(Order o, PaymentDetails d) { /* UPI collect request */ return PaymentResult.pending(); }
}

@Service
public class PaymentService {                                                 // the context
    private final Map<PaymentMethod, PaymentStrategy> strategies;
    public PaymentService(List<PaymentStrategy> all) {
        this.strategies = all.stream().collect(Collectors.toUnmodifiableMap(PaymentStrategy::method, s -> s));
    }
    public PaymentResult pay(Order order, PaymentDetails details) {
        PaymentStrategy s = strategies.get(details.method());
        if (s == null) throw new UnsupportedPaymentMethodException(details.method());
        return s.pay(order, details);                                          // no switch: add a method = add a bean
    }
}

Key points to cover:

  • For small, stateless algorithms, the strategy is a functional interface:
    • Comparator<T>, Function<Order, BigDecimal>;
    • list.sort(Comparator.comparing(Order::total).reversed()) is Strategy.

Q6. What are the benefits of using Strategy to select algorithms at runtime?

Short answer:

  • Open/Closed: a new algorithm means a new class, and the context doesn't change.
  • No conditional sprawl in the client.
  • Single responsibility: each algorithm is small, and tested in isolation.
  • Runtime flexibility: selection by configuration, feature flag, A/B test, tenant or region.
  • Easy mocking of the context's collaborators.

The costs:

  • More classes.
  • Clients or configuration must know which strategy to pick. Put that logic in one place, such as a registry or factory.
  • All strategies must fit one interface, which can force awkward parameters.

Q7. Give an example where Strategy simplifies managing multiple algorithms.

Short answer: Payment processing (above). Another common one is shipping-cost calculation: flat rate, weight-based, distance-based, a free-shipping promo, and a per-carrier API quote. Without Strategy, one method grows a switch with carrier-specific branches, which every change touches. With Strategy:

  • each calculator is a bean;
  • the right one is chosen from the order's region and carrier;
  • new carriers are added without touching the checkout code;
  • the calculations can be compared side by side in tests.

Q8. What is the Template Method pattern, and when would you use it?

Short answer: Use it when several classes share the same process, and only specific steps differ, and you want the base class to guarantee the order and the common behaviour: opening and closing resources, validation, logging, metrics, transactions. Examples:

  • file importers (CSV, XML, JSON);
  • report generators (gather, format, deliver);
  • test fixtures;
  • game turns;
  • framework lifecycles.

Q9. How would you implement the Template Method pattern in Java?

Short answer: Write an abstract class with a final template method that calls the steps in order. Make the steps abstract (mandatory) or hooks (overridable methods with default behaviour). Subclasses override only the steps.

public abstract class DataImporter<T> {
    public final ImportReport run(Path file) {                  // the template method: final, so the order can't change
        List<String> lines = read(file);
        List<T> records = lines.stream().map(this::parse).toList();
        List<T> valid = records.stream().filter(this::isValid).toList();   // hook with a default
        save(valid);
        afterImport(valid);                                      // optional hook
        return new ImportReport(records.size(), valid.size());
    }
    protected List<String> read(Path file) {                     // shared step
        try { return Files.readAllLines(file); } catch (IOException e) { throw new UncheckedIOException(e); }
    }
    protected abstract T parse(String line);                    // mandatory steps
    protected abstract void save(List<T> records);
    protected boolean isValid(T record) { return true; }        // hooks
    protected void afterImport(List<T> records) { }
}

public class CustomerCsvImporter extends DataImporter<Customer> {
    private final CustomerRepository repo;
    public CustomerCsvImporter(CustomerRepository repo) { this.repo = repo; }
    protected Customer parse(String line) { String[] f = line.split(","); return new Customer(f[0], f[1]); }
    protected void save(List<Customer> cs) { repo.saveAll(cs); }
    @Override protected boolean isValid(Customer c) { return c.email().contains("@"); }
}

Key points to cover:

  • Make the template method final, and the steps protected, so subclasses can't break the sequence, and clients can't call steps out of order.
  • This is the Hollywood principle: "don't call us, we'll call you". The base class calls the subclass.

Q10. Give an example where you'd use the Template Method pattern.

Short answer: A data-processing application that ingests from files, databases and APIs. The workflow (connect, fetch, parse, validate, save, and report) is identical. Only the fetching and parsing differ, so each source is a subclass that overrides those two steps.

Key points to cover:

  • Real framework examples:
    • AbstractList/AbstractMap in the JDK: implement get/size, and inherit the rest.
    • HttpServlet.service(), which dispatches to the doGet/doPost you override.
    • JUnit's lifecycle (@BeforeEach, the test, @AfterEach).
    • Spring Batch's ItemReader/ItemProcessor/ItemWriter steps.
    • Spring's AbstractRoutingDataSource (override determineCurrentLookupKey()).
  • Spring's JdbcTemplate/RestTemplate/TransactionTemplate fix the workflow, but take the variable part as a callback (RowMapper, TransactionCallback). That's the strategy/callback variant of the same idea, without inheritance.

Q11. What are the advantages and limitations of Template Method?

Short answer:

  • Advantages:
    • Code reuse: the shared steps live in one place.
    • Enforced ordering and invariants: resources are always closed, and validation always happens.
    • Subclasses only write what differs.
    • A clear extension point for frameworks.
  • Limitations:
    • Inheritance coupling: subclasses depend on the base class's internals (the "fragile base class" problem).
    • You can only vary one dimension, since Java has single inheritance.
    • The algorithm is fixed at compile time.
    • Deep hierarchies are hard to follow.
    • Liskov violations when overrides break the base's assumptions.
    • Testing a step often requires a subclass.

When the variation grows, refactor to Strategy: pass the steps in as collaborators or lambdas.

Q12. Show Template Method refactored into a strategy/callback.

Short answer: Keep the fixed workflow in a concrete class, and inject the variable steps. This is exactly how JdbcTemplate works.

public final class Importer {
    public <T> ImportReport run(Path file, Function<String, T> parser, Predicate<T> validator, Consumer<List<T>> saver) {
        List<T> records = readLines(file).stream().map(parser).toList();
        List<T> valid = records.stream().filter(validator).toList();
        saver.accept(valid);
        return new ImportReport(records.size(), valid.size());
    }
}
importer.run(path, CustomerCsv::parse, c -> c.email().contains("@"), customerRepo::saveAll);

Follow-up questions this topic invites — and their answers

Q: Strategy vs State? A: They have the same structure: a context delegates to an interface. In Strategy, the client picks the algorithm, and the strategies don't know each other. In State, the state objects themselves trigger transitions to other states, as the context's internal state changes (an order moving from Created to Paid to Shipped).

Q: How do you select a strategy without a switch statement? A: Use a Map<Key, Strategy> built from injected beans; have each strategy declare supports(input) and pick the first match; or use an enum whose constants each implement the strategy's method.

Q: Enum-based strategies: when are they appropriate? A: When the set of algorithms is closed and small, and the algorithms are stateless. For example, enum Operation { PLUS { int apply(...) }, MINUS { ... } }. For an open-ended set, or algorithms with dependencies, use Spring beans.

Q: Why prefer composition over inheritance here? A: Composition can be swapped at runtime, combined across several dimensions, and tested with mocks, and it avoids fragile base classes. Inheritance is fine when the base class truly owns an invariant workflow, and the variation points are few and stable.

Previous

Chain of Responsibility & Observer Patterns — Interview Questions

Next

Command Pattern — Interview Questions

AI Tutor

Lesson: Strategy & Template Method Patterns — Interview Questions

Quick actions

AI responses can be inaccurate. Verify critical information.