工厂+策略最佳实践
文章目录
1.目录结构
2.SubjectType.java 策略枚举类
package com.sunxiansheng.design_pattern.factory_strategy.strategyenum;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Description: 题目类型,分为单选、多选、判断、简答
*
* @Author sun
* @Create 2024/9/8 21:11
* @Version 1.0
*/
public enum SubjectType {
// 单选题
SINGLE_CHOICE(1, "单选题"),
// 多选题
MULTIPLE_CHOICE(2, "多选题"),
// 判断题
JUDGMENT(3, "判断题"),
// 简答题
SHORT_ANSWER(4, "简答题");
private int code;
private String desc;
SubjectType(int code, String desc) {
this.code = code;
this.desc = desc;
}
// get方法
public int getCode() {
return code;
}
public String getDesc() {
return desc;
}
// 将枚举转为map
public static Map<Integer, SubjectType> enumeratedMaps = Stream.of(SubjectType.values())
.collect(Collectors.toMap(SubjectType::getCode, Function.identity()));
/**
* 根据code获取题目类型
*
* @param code
* @return
*/
public static SubjectType getSubjectType(int code) {
return enumeratedMaps.get(code);
}
}
3.ISubjectStrategy.java 策略接口
package com.sunxiansheng.design_pattern.factory_strategy.strategy;
import com.sunxiansheng.design_pattern.factory_strategy.strategyenum.SubjectType;
/**
* Description: 题目策略
*
* @Author sun
* @Create 2025/2/11 12:06
* @Version 1.0
*/
public interface ISubjectStrategy {
/**
* 获取题目类型
*
* @return
*/
SubjectType getSubjectType();
/**
* 处理题目
*/
void handleQuestion();
}
4.策略接口实现类
1.Judgment.java
package com.sunxiansheng.design_pattern.factory_strategy.strategy;
import com.sunxiansheng.design_pattern.factory_strategy.strategyenum.SubjectType;
/**
* Description: 判断题策略
*
* @Author sun
* @Create 2024/9/8 21:22
* @Version 1.0
*/
public class Judgment implements ISubjectStrategy {
@Override
public void handleQuestion() {
System.out.println("处理判断题");
}
@Override
public SubjectType getSubjectType() {
return SubjectType.JUDGMENT;
}
}
2.MultipleChoice.java
package com.sunxiansheng.design_pattern.factory_strategy.strategy;
import com.sunxiansheng.design_pattern.factory_strategy.strategyenum.SubjectType;
/**
* Description: 多选题策略
*
* @Author sun
* @Create 2024/9/8 21:21
* @Version 1.0
*/
public class MultipleChoice implements ISubjectStrategy {
@Override
public void handleQuestion() {
System.out.println("处理多选题");
}
@Override
public SubjectType getSubjectType() {
return SubjectType.MULTIPLE_CHOICE;
}
}
3.ShortAnswer.java
package com.sunxiansheng.design_pattern.factory_strategy.strategy;
import com.sunxiansheng.design_pattern.factory_strategy.strategyenum.SubjectType;
/**
* Description: 简答题策略
*
* @Author sun
* @Create 2024/9/8 21:22
* @Version 1.0
*/
public class ShortAnswer implements ISubjectStrategy {
@Override
public void handleQuestion() {
System.out.println("处理简答题");
}
@Override
public SubjectType getSubjectType() {
return SubjectType.SHORT_ANSWER;
}
}
4.SingleChoice.java
package com.sunxiansheng.design_pattern.factory_strategy.strategy;
import com.sunxiansheng.design_pattern.factory_strategy.strategyenum.SubjectType;
/**
* Description: 单选题策略
*
* @Author sun
* @Create 2024/9/8 21:20
* @Version 1.0
*/
public class SingleChoice implements ISubjectStrategy {
@Override
public void handleQuestion() {
System.out.println("处理单选题");
}
@Override
public SubjectType getSubjectType() {
return SubjectType.SINGLE_CHOICE;
}
}
5.Strategy.java 策略工厂
package com.sunxiansheng.design_pattern.factory_strategy.factory;
import com.sunxiansheng.design_pattern.factory_strategy.strategy.ISubjectStrategy;
import com.sunxiansheng.design_pattern.factory_strategy.strategyenum.SubjectType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Description: 策略工厂
*
* @Author sun
* @Create 2024/9/8 21:23
* @Version 1.0
*/
public class Strategy {
/**
* 正常情况下是使用Spring的依赖注入,这里直接使用反射模拟了
*/
private List<ISubjectStrategy> strategies = new ArrayList<>();
/**
* 策略map,将list转为map,方便根据题目类型获取策略
*/
private Map<SubjectType, ISubjectStrategy> strategyMap = new HashMap<>();
{
// 反射模拟Spring的依赖注入
try {
Class<?> singleChoice = Class.forName("com.sunxiansheng.design_pattern.factory_strategy.strategy.SingleChoice");
Class<?> multipleChoice = Class.forName("com.sunxiansheng.design_pattern.factory_strategy.strategy.MultipleChoice");
Class<?> judgment = Class.forName("com.sunxiansheng.design_pattern.factory_strategy.strategy.Judgment");
Class<?> shortAnswer = Class.forName("com.sunxiansheng.design_pattern.factory_strategy.strategy.ShortAnswer");
strategies.add((ISubjectStrategy) singleChoice.newInstance());
strategies.add((ISubjectStrategy) multipleChoice.newInstance());
strategies.add((ISubjectStrategy) judgment.newInstance());
strategies.add((ISubjectStrategy) shortAnswer.newInstance());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
{
// 将list转为map
strategies.forEach(strategy -> strategyMap.put(strategy.getSubjectType(), strategy));
}
/**
* 根据题目类型获取策略
*
* @param subjectType
* @return
*/
public ISubjectStrategy getStrategy(SubjectType subjectType) {
return strategyMap.get(subjectType);
}
}
6.Client.java 客户端
package com.sunxiansheng.design_pattern.factory_strategy;
import com.sunxiansheng.design_pattern.factory_strategy.factory.Strategy;
import com.sunxiansheng.design_pattern.factory_strategy.strategyenum.SubjectType;
/**
* Description: 客户端
*
* @Author sun
* @Create 2024/9/8 21:34
* @Version 1.0
*/
public class Client {
public static void main(String[] args) {
// 策略工厂
Strategy strategy = new Strategy();
// 四种策略
strategy.getStrategy(SubjectType.SINGLE_CHOICE).handleQuestion();
strategy.getStrategy(SubjectType.MULTIPLE_CHOICE).handleQuestion();
strategy.getStrategy(SubjectType.JUDGMENT).handleQuestion();
strategy.getStrategy(SubjectType.SHORT_ANSWER).handleQuestion();
}
}
7.小结
工厂+策略首先要有一个策略的枚举类,设置四种题目类型的枚举,然后一个策略接口,有两个方法,一个方法返回当前策略的枚举类型,另一个方法就是对目前题目类型的处理逻辑,去实现接口即可。接下来就要实现一个策略工厂,使用Spring的属性注入,将四种策略注入进来,然后在Bean的初始化阶段,将四种策略的List转换为Map,最后提供一个get方法,可以根据题目类型的枚举去获取不同的策略。
作者:S-X-S