SpringBoot中模版方法+工厂模式+策略模式组合使用案例

代码实现步骤

  1. 定义模板方法抽象接口
    定义一个抽象接口 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");
    }
}
  1. 定义策略接口
    策略接口 TemplateStrategy 继承 AbstractTemplate,这样具体的策略类可以直接使用模板方法的框架。
public interface TemplateStrategy extends AbstractTemplate {
}
  1. 创建具体策略类
    创建两个具体策略类 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 实现
}
  1. 创建策略工厂
    通过 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;
    }
}
  1. 使用策略模式和工厂模式
    在 Service 中使用工厂模式获取具体的策略对象,并调用其方法。
@Service
public class TemplateService {

    @Autowired
    private TemplateStrategyFactory strategyFactory;

    public void executeStrategy(String type) {
        TemplateStrategy strategy = strategyFactory.getStrategy(type);
        strategy.execute(); // 调用模板方法
    }
}
  1. 创建 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!";
    }
}
  1. 运行项目
    启动 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 注解,无需修改工厂类。

灵活性:客户端可以通过参数动态选择不同的策略。

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐