Applying the Strategy Pattern with Simple Factory in a Spring Boot Application
This article demonstrates how to apply the Strategy pattern combined with a simple factory in a Spring Boot application, showing interface definition, multiple arithmetic strategy implementations, a factory that registers beans, a service invoking strategies via a map, and a REST controller for testing, highlighting extensibility.
Many developers have heard of the Strategy pattern but may not know how to use it effectively in a real project. This article presents a concrete scenario: integrating a third‑party OA system that calls back to our service with different business branches distinguished by a request field.
Instead of writing separate callback interfaces or a long if…else chain, the author demonstrates a clean solution using a Strategy interface combined with a simple factory.
Strategy Interface
public interface CalculationStrategy {
/**
* Strategy method
*/
int operate(int num1, int num2);
}Concrete Strategies – four arithmetic implementations are provided:
@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 test implementation without a bean name is also shown to illustrate the default naming behavior.
@Component
class TestStrategyImpl implements CalculationStrategy {
@Override
public int operate(int num1, int num2) {
return num1 - num2;
}
}Strategy Factory (Context)
@Component
public class CalculationFactory {
/**
* Map of beanName -> strategy instance
*/
public final Map
calculationStrategyMap = Maps.newHashMapWithExpectedSize(4);
/**
* Constructor registers all strategies at startup
*/
public CalculationFactory(Map
strategyMap) {
this.calculationStrategyMap.clear();
this.calculationStrategyMap.putAll(strategyMap);
}
public Map
getCalculationStrategyMap() {
return calculationStrategyMap;
}
}The factory receives all @Component beans that implement CalculationStrategy and stores them in a map keyed by the bean name.
Service Layer
@Service
public class CalculationService {
@Autowired
private CalculationFactory calculationFactory;
public int operateByStrategy(String strategy, int num1, int num2) {
// Defensive check for missing strategy can be added here
return calculationFactory.getCalculationStrategyMap().get(strategy).operate(num1, num2);
}
}The service looks up the appropriate strategy from the factory and delegates the calculation.
REST Controller for Testing
@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) {
// Parameter validation omitted for brevity
return calculationService.operateByStrategy(operation, num1, num2);
}
}Calling /strategy/test/add/3/5 returns 8 , while /strategy/test/division/10/2 returns 5 . The result screenshot is shown in the original article.
The main advantage of this design is extensibility: adding a new business branch only requires creating a new CalculationStrategy implementation and annotating it with @Component . No changes are needed in the service or controller, keeping the system modular and maintainable.
The author concludes with a modest note, inviting readers to like the article and share feedback.
Architect
Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.
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.