Strategy Pattern in Spring Boot: Extensible Interface Design Without If-Else Chains
This tutorial demonstrates implementing the Strategy Pattern in Spring Boot using a calculator example, showing how to register strategy beans via @Component, inject them into a factory map at startup, and route requests dynamically for extensible callback handling without modifying existing code.
The article addresses a common integration scenario: a third-party OA system callbacks into the current system with different business types distinguished by a field. Instead of writing multiple endpoints or a large if-else chain, the author applies the Strategy Pattern combined with a simple factory to achieve clean extensibility.
Strategy Interface
First, a CalculationStrategy interface defines the contract:
public interface CalculationStrategy { int operate(int num1, int num2); }Concrete Strategies
Each business branch becomes a Spring bean implementing the interface, annotated with @Component("beanName") where the bean name serves as the routing key:
@Component("add") class AddCalculationStrategyImpl implements CalculationStrategy { @Override public int operate(int num1, int num2) { return num1 + num2; } } @Component("Division") class DivisionStrategyImpl implements CalculationStrategy { @Override public int operate(int num1, int num2) { return num1 / num2; } } @Component("multiple") class MultiplicationStrategyImpl implements CalculationStrategy { @Override public int operate(int num1, int num2) { return num1 * num2; } } @Component("subtract") class SubtractionStrategyImpl implements CalculationStrategy { @Override public int operate(int num1, int num2) { return num1 - num2; } }A fifth implementation TestStrategyImpl without an explicit bean name defaults to the camel-case class name.
Strategy Factory (Context)
The CalculationFactory acts as the registry. Spring injects a map of all CalculationStrategy beans (key = bean name, value = instance) into the constructor at startup. The factory stores them in a Guava Map<String, CalculationStrategy> for O(1) lookup:
@Component public class CalculationFactory { public final Map<String, CalculationStrategy> calculationStrategyMap = Maps.newHashMapWithExpectedSize(4); public CalculationFactory(Map<String, CalculationStrategy> strategyMap) { this.calculationStrategyMap.clear(); this.calculationStrategyMap.putAll(strategyMap); } public Map<String, CalculationStrategy> getCalculationStrategyMap() { return calculationStrategyMap; } }Service Layer Routing
CalculationServiceuses the factory to retrieve the strategy by key and execute it. The author notes that map.get() may return null, so production code should add null-safety handling:
@Service public class CalculationService { @Autowired private CalculationFactory calculationFactory; public int operateByStrategy(String strategy, int num1, int num2) { // TODO: add null check for production return calculationFactory.getCalculationStrategyMap().get(strategy).operate(num1, num2); } }Controller for Testing
A REST endpoint exposes the routing:
@RestController @RequestMapping("/strategy") public class TestStrategyController { @Autowired private CalculationService calculationService; @GetMapping("/test/{operation}/{num1}/{num2}") public int testCalculation(@PathVariable String operation, @PathVariable int num1, @PathVariable int num2) { return calculationService.operateByStrategy(operation, num1, num2); } }Extensibility Benefit
Adding a new business branch only requires creating a new @Component implementation of CalculationStrategy. No changes to the factory, service, or controller are needed. The new bean is automatically registered at startup, and the routing key becomes the new bean name.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
IoT Full-Stack Technology
Dedicated to sharing IoT cloud services, embedded systems, and mobile client technology, with no spam ads.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
