Skip to content

策略模式

基本原理

定义文件类型

java
public interface FileType {

    static final String CSV = "CSV";

    static final String XML = "XML";

    static final String JSON = "JSON";

}

定义多种解析器

java
public interface FileParser {
    void parse(File file);
}
java
@Component(FileType.CSV)
public class CsvFileParser implements FileParser {
    @Override
    public void parse(File file) {
        System.out.println("解析CSV文件");
    }
}
java
@Component(FileType.JSON)
public class JsonFileParser implements FileParser {
    @Override
    public void parse(File file) {
        System.out.println("解析JSON文件");
    }
}
java
@Component(FileType.XML)
public class XmlFileParser implements FileParser {
    @Override
    public void parse(File file) {
        System.out.println("解析XML文件");
    }
}

定义工厂类

java
@Component
public class FileParserFactory {

    private final Map<String, FileParser> fileParsers;

    // beanName 作为 key
    public FileParserFactory(Map<String, FileParser> fileParsers) {
        this.fileParsers = fileParsers;
    }

    public FileParser get(String fileType) {
        FileParser fileParser = fileParsers.get(fileType);
        if (Objects.isNull(fileParser)) {
            throw new IllegalArgumentException("不支持的文件类型");
        }
        return fileParser;
    }

}

定义服务类

java
@Service
public class ProcessService {

    private final FileParserFactory fileParserFactory;

    public ProcessService(FileParserFactory fileParserFactory) {
        this.fileParserFactory = fileParserFactory;
    }

    public void parse(File file, String fileType) {
        FileParser fileParser = fileParserFactory.get(fileType);
        fileParser.parse(file);
    }

}

实现方式一

以支付方式为例

定义支付方式类型

java
public interface PayType {
    static final String ALIPAY = "ALIPAY"; // 支付宝支付
    static final String WX_PAY = "WX_PAY"; // 微信支付
}

定义支付接口和工厂

java
public interface PayHandler {
    void pay();  // 支付
    String getPayType(); // 获取支付方式
}
java
@Component
public class PayHandlerFactory {

    private final Map<String, PayHandler> payHandlers;

    // 默认 beanName 作为 key
    /*
     * 这里通过默认 beanName 作为 key 可以不实现接口的 getPayType
     * 只需要在实现类的接口上 @Component 指定具体的名称 key 即可
     *
     * 还有基于第二种的实现方式,通过枚举类型
     */
    public PayHandlerFactory(Map<String, PayHandler> payHandlers) {
        this.payHandlers = payHandlers;
    }

    public PayHandler getByType(String payType) {
        PayHandler payHandler = payHandlers.get(payType);
        if (Objects.isNull(payHandler)) {
            throw new IllegalArgumentException("不支持的支付方式");
        }
        return payHandler;
    }

}

定义实现类

java
@Component(PayType.ALIPAY)
public class AliPayHandler implements PayHandler {

    @Resource
    private AliPayService aliPayService;
    
    @Override
    public void pay() {
        // 支付宝支付具体逻辑
    }

    @Override
    public String getPayType() {
        return PayType.ALIPAY;
    }

}
java
@Component(PayType.WX_PAY)
public class WxPayHandler implements PayHandler {

    @Resource
    private WxPayService wxPayService;
    
    @Override
    public void pay() {
        // 微信支付具体逻辑
    }

    @Override
    public String getPayType() {
        return PayType.WX_PAY;
    }

}

实现方式二

以题目类型为例

定义题目类型(枚举)

java
@Getter
public enum SubjectInfoTypeEnum {

    RADIO(1, "单选"),
    MULTIPLE(2, "多选"),
    JUDGE(3, "判断"),
    BRIEF(4, "简答");

    public int code;
    public String desc;

    SubjectInfoTypeEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public static SubjectInfoTypeEnum getByCode(int codeVal) {
        for (SubjectInfoTypeEnum categoryTypeEnum : SubjectInfoTypeEnum.values()) {
            if (categoryTypeEnum.getCode() == codeVal) {
                return categoryTypeEnum;
            }
        }
        return null;
    }
}

定义题目接口和工厂

java
public interface SubjectTypeHandler {

    /**
     * 枚举身份识别
     *
     * @return SubjectInfoTypeEnum
     */
    SubjectInfoTypeEnum getHandlerType();

    /**
     * 实际题目插入
     *
     * @param subjectInfoBO
     */
    void add(SubjectInfoBO subjectInfoBO);

}
java
@Component
public class SubjectTypeHandlerFactory implements InitializingBean {

    @Resource
    private List<SubjectTypeHandler> subjectTypeHandlers;

    private Map<SubjectInfoTypeEnum, SubjectTypeHandler> handlerMap = new HashMap<>();

    public SubjectTypeHandler getSubjectTypeHandler(int subjectType) {
        SubjectInfoTypeEnum subjectInfoTypeEnum = SubjectInfoTypeEnum.getByCode(subjectType);
        return handlerMap.get(subjectInfoTypeEnum);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        for (SubjectTypeHandler subjectTypeHandler : subjectTypeHandlers) {
            handlerMap.put(subjectTypeHandler.getHandlerType(), subjectTypeHandler);
        }
    }

}

定义实现类

java
@Component
public class BriefTypeHandler implements SubjectTypeHandler {

    @Resource
    private SubjectBriefService subjectBriefService;

    @Override
    public SubjectInfoTypeEnum getHandlerType() {
        return SubjectInfoTypeEnum.BRIEF;
    }

    @Override
    public void add(SubjectInfoBO subjectInfoBO) {
        List<SubjectBrief> subjectBriefList = new LinkedList<>();
        subjectInfoBO.getOptionList().forEach(option -> {
            SubjectBrief subjectBrief = SubjectBriefConverter.INSTANCE.convertBOToEntity(option);
            subjectBrief.setSubjectId(subjectInfoBO.getId());
            subjectBrief.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
            subjectBriefList.add(subjectBrief);
        });
        subjectBriefService.batchInsert(subjectBriefList);
    }
}
java
@Component
public class JudgeTypeHandler implements SubjectTypeHandler {

    @Resource
    private SubjectJudgeService subjectJudgeService;

    @Override
    public SubjectInfoTypeEnum getHandlerType() {
        return SubjectInfoTypeEnum.JUDGE;
    }

    @Override
    public void add(SubjectInfoBO subjectInfoBO) {
        List<SubjectJudge> subjectJudgeList = new LinkedList<>();
        subjectInfoBO.getOptionList().forEach(option -> {
            SubjectJudge subjectJudge = SubjectJudgeConverter.INSTANCE.convertBOToEntity(option);
            subjectJudge.setSubjectId(subjectInfoBO.getId());
            subjectJudge.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
            subjectJudgeList.add(subjectJudge);
        });
        subjectJudgeService.batchInsert(subjectJudgeList);
    }
}
java
@Component
public class MultipleTypeHandler implements SubjectTypeHandler {

    @Resource
    private SubjectMultipleService subjectMultipleService;

    @Override
    public SubjectInfoTypeEnum getHandlerType() {
        return SubjectInfoTypeEnum.MULTIPLE;
    }

    @Override
    public void add(SubjectInfoBO subjectInfoBO) {
        List<SubjectMultiple> subjectMultipleList = new LinkedList<>();
        subjectInfoBO.getOptionList().forEach(option -> {
            SubjectMultiple subjectMultiple = SubjectMultipleConverter.INSTANCE.convertBOToEntity(option);
            subjectMultiple.setSubjectId(subjectInfoBO.getId());
            subjectMultiple.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
            subjectMultipleList.add(subjectMultiple);
        });
        subjectMultipleService.batchInsert(subjectMultipleList);
    }
}
java
@Component
public class RadioTypeHandler implements SubjectTypeHandler {

    @Resource
    private SubjectRadioService subjectRadioService;

    @Override
    public SubjectInfoTypeEnum getHandlerType() {
        return SubjectInfoTypeEnum.RADIO;
    }

    @Override
    public void add(SubjectInfoBO subjectInfoBO) {
        List<SubjectRadio> subjectRadioList = new LinkedList<>();
        subjectInfoBO.getOptionList().forEach(option -> {
            SubjectRadio subjectRadio = SubjectRadioConverter.INSTANCE.convertBOToEntity(option);
            subjectRadio.setSubjectId(subjectInfoBO.getId());
            subjectRadio.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
            subjectRadioList.add(subjectRadio);
        });
        subjectRadioService.batchInsert(subjectRadioList);
    }
}

更新: 2025-07-21 12:54:36
原文: https://www.yuque.com/lsxxyg/sz/ywk2fdird3pwtezk