策略模式是属于设计模式中的行为模式中的一种,策略模式主要解决选项过多的问题,避免大量的if else 和 switch下有太多的case。
策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。
1.创建抽象策略接口
public interface ReportStrategy extends InitializingBean { /** * 构建上报数据,不同广告商、不同阶段构造的数据是不同的 * @param clueDetail * @return */ <T extends ReportReqBO> T buildReturnData(AdClueDetail clueDetail); /** * 上报 * @param data * @param <T> * @return */ <T extends ReportReqBO> Object report(T data);
}
2.创建策略工厂
@Slf4j @Getter public class ReportStrategyFactory {
/** * 上报策略map */ private final Map<String, ReportStrategy> reportStrategyMap = new ConcurrentHashMap<>(16); private static final ReportStrategyFactory INSTANCE = new ReportStrategyFactory(); private ReportStrategyFactory() { }
public static ReportStrategyFactory getInstance() { return INSTANCE; } /** * 构建上报策略的key * @param reportTarget * @param stageType * @return */ public String buildReportKey(ReportTargetEnum reportTarget, StageTypeEnum stageType) { if (reportTarget == null || stageType == null) { log.warn("【策略key不能为空】,reportTarget:{},stageType:{}", reportTarget, stageType); return null; } return reportTarget.getKey().concat(Constants.DELIMITER_DOT).concat(stageType.getKey()); }
3.创建接口实现类
@Slf4j public abstract class DefaultReportService implements ReportStrategy {
@Autowired private ReportService reportService; @Overridepublic KuaiShouClueBackReqBO buildReturnData(AdClueDetail adClueDetail) {
assemblyParams(adClueDetail,backReqDTO); return kuaiShouClueBackReqBO; } @Override public <T extends ReportReqBO> Object report(T data) { return updateResponseDTO; } /** * 组装回传参数 Assembly parameters * * @param adClueDetail adClueDetail * @param backReqDTO backReqDTO * @return key */ public abstract void assemblyParams(AdClueDetail adClueDetail, KuaiShouBackReqDTO backReqDTO); /** * 获取阶段 * * @return 阶段 */ public abstract StageTypeEnum getStage(); }
3.(1)具体策略A
@Slf4j @Component public class ClueIntentionStrategy extends DefaultReportService { @Override public void assemblyParams(AdClueDetail adClueDetail, KuaiShouBackReqDTO backReqDTO) { // 做你的业务 } @Override public StageTypeEnum getStage() { return StageTypeEnum.CLUE_INTENTION; } /** * 把策略放入map */ @Override public void afterPropertiesSet() throws Exception { ReportStrategyFactory reportStrategyFactory = ReportStrategyFactory.getInstance(); String key = reportStrategyFactory.buildReportKey(ReportTargetEnum.KUAISHOU, getStage()); reportStrategyFactory.getReportStrategyMap().put(key, this); } }
3.(2)具体策略B
@Slf4j @Component public class ClueValidityStrategy extends DefaultReportService { @Override public void assemblyParams(AdClueDetail adClueDetail, KuaiShouBackReqDTO backReqDTO) { // 做你的业务 } @Override public StageTypeEnum getStage() { return StageTypeEnum.CLUE_VALIDITY; } /** * 把策略放入map */ @Override public void afterPropertiesSet() throws Exception { ReportStrategyFactory reportStrategyFactory = ReportStrategyFactory.getInstance(); String key = reportStrategyFactory.buildReportKey(ReportTargetEnum.KUAISHOU, getStage()); reportStrategyFactory.getReportStrategyMap().put(key, this); } }
1.优点
- 算法可以自由切换
- 避免使用多重条件判断(如果不用策略模式我们可能会使用多重条件语句,不利于维护)
- 扩展性良好,增加一个策略只需实现接口即可
2.缺点
- 策略类数量会增多,每个策略都是一个类,复用的可能性很小
- 所有的策略类都需要对外暴露
标签:return,策略,模式,adClueDetail,ReportStrategyFactory,key,设计模式,public From: https://www.cnblogs.com/chuhecc/p/17772444.html