前言
最近在做一个问卷调查的功能,该系统可以预见的后续肯定会增加题型,所以为了以后拓展题型的方便,此处在存储问卷题型的时候采用了策略模式,下面简单介绍一下spring注入的策略模式的应用
简介
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了对象之间的一种动态的交互结构,使得不同的对象可以采用不同的方法来达到同样的目的。通俗的讲,策略模式是一种“行为型”的设计模式,它定义了对象之间的接口,但并不告诉我们如何实现这些接口,而是告诉我们如何使用这些接口。
策略模式可以解决的问题
- 对象之间的交互需要动态地选择合适的行为。
- 对象之间的交互需要考虑对象的行为和状态。
- 对象之间的交互需要支持多态性。
特点
- 提供了一组接口,这些接口定义了不同的对象之间的行为和交互方式。
- 隐藏了实现细节,只提供接口,使得使用者可以更加灵活地使用这些接口。
- 支持多态性,即不同的对象可以采用不同的实现方式,以满足不同的需求。
- 策略模式不是一次性的解决方案,而是可以被多次重复使用。
应用示例
定义一个接口
public interface QuestionStrategy {
/**
* 执行策略前
*/
void strategyBefore();
/**
* 执行策略
*
* @param surveyId 问卷id
* @param questionId 问题id
* @param optionItems 问题分项Json
* @param required 是否必填
* @return JSONArray
*/
JSONArray strategy(Long surveyId, Long questionId, JSONArray optionItems, Boolean required);
/**
* 执行策略后
*/
void strategyAfter();
/**
* 获取问题类型
*
* @return 问题类型
*/
String getQuestionType();
}
实现此接口
@Component
public class QuestionCheckboxStrategyImpl implements QuestionStrategy {
private final DefaultIdentifierGenerator defaultIdentifierGenerator = new DefaultIdentifierGenerator();
public QuestionCheckboxStrategyImpl(MybatisBatchUtils mybatisBatchUtils) {
this.mybatisBatchUtils = mybatisBatchUtils;
}
@Override
public void strategyBefore() {
}
@Override
public JSONArray strategy(Long surveyId, Long questionId, JSONArray optionItems, Boolean required) {
//xxx自己的处理逻辑
return optionItemsCopy;
}
@Override
public void strategyAfter() {
}
@Override
public String getQuestionType() {
//获取到当前问题类型
return QuestionTypeEnums.CHECKBOX.getValue();
}
}
定义一个获取策略的工厂,当需要有新问题假如是只需要调用QuestionStrategyFactory中的getQuestionStrategy方法传入当前问题的类型就可以获取到对应的策略
@Component
@Slf4j
public class QuestionStrategyFactory {
private final Map<String, QuestionStrategy> strategyContext = new HashMap<>();
public QuestionStrategyFactory(List<QuestionStrategy> questionStrategyList) {
for (QuestionStrategy questionStrategy : questionStrategyList) {
strategyContext.put(questionStrategy.getQuestionType(), questionStrategy);
}
}
/**
* 根据问题类型获取策略服务类
*
* @param type 问题类型
* @return QuestionStrategy
*/
public QuestionStrategy getQuestionStrategy(String type) {
QuestionStrategy questionStrategy = strategyContext.get(type);
if (ObjectUtil.isEmpty(questionStrategy)) {
log.warn("当前问题类型[{}]未获取到策略实现类",type);
}
return questionStrategy;
}
}