Strategy Pattern in Spring Boot: Extensible Interface Design for Multi-Business Callbacks
This article demonstrates how to implement the Strategy Pattern combined with a Simple Factory in Spring Boot to handle multiple business callbacks through a single interface, enabling easy extension without modifying existing code.
The author presents a practical implementation of the Strategy Pattern in Spring Boot to solve a real-world integration scenario: a third-party OA system callbacks different business interfaces, distinguished by a single field. Instead of creating multiple endpoints or using lengthy if-else chains, the solution uses a single interface plus the Strategy Pattern and Simple Factory for clean routing.
Core Components
1. Strategy Interface
Defines the contract for all business operations. The example uses a calculator analogy with an operate(int num1, int num2) method.
public interface CalculationStrategy {
int operate(int num1, int num2);
}2. Concrete Strategies
Each business branch implements the interface and is registered as a Spring bean with a unique name via @Component("name"). The article shows four implementations: addition, subtraction, multiplication, and division.
@Component("add")
class AddCalculationStrategyImpl 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;
}
}
@Component("multiple")
class MultiplicationStrategyImpl 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;
}
}The author notes that if @Component value is omitted, Spring defaults to the camelCase class name (e.g., testStrategyImpl).
3. Strategy Factory (Context)
The factory acts as a registry. At application startup, Spring injects a map of all beans implementing CalculationStrategy (key = bean name, value = instance). The constructor stores this map for later 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;
}
}The author uses Guava's Maps.newHashMapWithExpectedSize(4) for initialization.
4. Service Layer Routing
The service retrieves the appropriate strategy from the factory map using the incoming strategy key and executes it. A comment warns that map.get() may return null, so production code should add null-checks or fallback handling.
@Service
public class CalculationService {
@Autowired
private CalculationFactory calculationFactory;
public int operateByStrategy(String strategy, int num1, int num2) {
// Null safety needed here in production
return calculationFactory.getCalculationStrategyMap().get(strategy).operate(num1, num2);
}
}5. Controller Endpoint
A REST controller exposes a test endpoint accepting the operation name and two numbers as path variables.
@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
return calculationService.operateByStrategy(operation, num1, num2);
}
}Benefits and Extensibility
The author emphasizes that adding a new business branch only requires creating a new implementation of CalculationStrategy annotated with @Component. No changes to the factory, service, or controller are needed. This adheres to the Open/Closed Principle and isolates business logic per branch.
The article concludes with a note that this is a simplified demo and invites feedback for improvement.
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.
