设计模式-SpringBoot中模版方法+工厂模式+策略模式组合使用案例
模板方法抽象接口:将模板方法的框架定义在抽象接口中,具体的策略类只需实现具体的步骤。动态注入策略类型:策略的类型通过 @Component 注解动态注入,而不是在工厂中写死。扩展性:新增策略时,只需创建一个新的策略类并标记 @Component 注解,无需修改工厂类。灵活性:客户端可以通过参数动态选择不同的策略。
·
SpringBoot中模版方法+工厂模式+策略模式组合使用案例
代码实现步骤
- 定义模板方法抽象接口
定义一个抽象接口 AbstractTemplate,其中包含模板方法的框架。
public abstract class AbstractTemplate {
// 模板方法,定义了算法的框架
public final void execute() {
step1();
step2();
step3();
}
// 具体步骤1,子类必须实现
protected abstract void step1();
// 具体步骤2,子类必须实现
protected abstract void step2();
// 具体步骤3,子类可以选择重写
protected void step3() {
System.out.println("AbstractTemplate: Default implementation of step3");
}
}
- 定义策略接口
策略接口 TemplateStrategy 继承 AbstractTemplate,这样具体的策略类可以直接使用模板方法的框架。
public interface TemplateStrategy extends AbstractTemplate {
}
- 创建具体策略类
创建两个具体策略类 ConcreteStrategyA 和 ConcreteStrategyB,它们分别实现 TemplateStrategy 接口。
@Component("A") // 使用注解标记策略类型
public class ConcreteStrategyA implements TemplateStrategy {
@Override
public void step1() {
System.out.println("ConcreteStrategyA: Step 1");
}
@Override
public void step2() {
System.out.println("ConcreteStrategyA: Step 2");
}
@Override
public void step3() {
System.out.println("ConcreteStrategyA: Custom implementation of step3");
}
}
@Component("B") // 使用注解标记策略类型
public class ConcreteStrategyB implements TemplateStrategy {
@Override
public void step1() {
System.out.println("ConcreteStrategyB: Step 1");
}
@Override
public void step2() {
System.out.println("ConcreteStrategyB: Step 2");
}
// 使用默认的 step3 实现
}
- 创建策略工厂
通过 Spring 的依赖注入动态获取所有策略对象,并将其存储在一个 Map 中。策略的类型通过 @Component 注解标记。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class TemplateStrategyFactory {
private final Map<String, TemplateStrategy> strategies = new HashMap<>();
@Autowired
public TemplateStrategyFactory(ApplicationContext context) {
// 从 Spring 容器中获取所有 TemplateStrategy 的实现类
Map<String, TemplateStrategy> beans = context.getBeansOfType(TemplateStrategy.class);
for (Map.Entry<String, TemplateStrategy> entry : beans.entrySet()) {
// 获取策略类型(通过 @Component 注解的值)
String type = entry.getKey();
strategies.put(type, entry.getValue());
}
}
public TemplateStrategy getStrategy(String type) {
TemplateStrategy strategy = strategies.get(type);
if (strategy == null) {
throw new IllegalArgumentException("Unknown strategy type: " + type);
}
return strategy;
}
}
- 使用策略模式和工厂模式
在 Service 中使用工厂模式获取具体的策略对象,并调用其方法。
@Service
public class TemplateService {
@Autowired
private TemplateStrategyFactory strategyFactory;
public void executeStrategy(String type) {
TemplateStrategy strategy = strategyFactory.getStrategy(type);
strategy.execute(); // 调用模板方法
}
}
- 创建 Controller
在 Controller 中调用 Service 的方法。
@RestController
@RequestMapping("/template")
public class TemplateController {
@Autowired
private TemplateService templateService;
@GetMapping("/execute")
public String executeStrategy(@RequestParam String type) {
templateService.executeStrategy(type);
return "Strategy executed!";
}
}
- 运行项目
启动 Spring Boot 应用程序,并访问以下 URL:
http://localhost:8080/template/execute?type=A
http://localhost:8080/template/execute?type=B
输出结果:
访问 type=A 时:
ConcreteStrategyA: Step 1
ConcreteStrategyA: Step 2
ConcreteStrategyA: Custom implementation of step3
访问 type=B 时:
ConcreteStrategyB: Step 1
ConcreteStrategyB: Step 2
AbstractTemplate: Default implementation of step3
总结
模板方法抽象接口:将模板方法的框架定义在抽象接口中,具体的策略类只需实现具体的步骤。
动态注入策略类型:策略的类型通过 @Component 注解动态注入,而不是在工厂中写死。
扩展性:新增策略时,只需创建一个新的策略类并标记 @Component 注解,无需修改工厂类。
灵活性:客户端可以通过参数动态选择不同的策略。
更多推荐
所有评论(0)