设计模式之~策略模式

策略模式是属于设计模式中的行为模式中的一种,策略模式主要解决选项过多的问题,避免大量的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.缺点

  • 策略类数量会增多,每个策略都是一个类,复用的可能性很小
  • 所有的策略类都需要对外暴露

 

posted @ 2023-10-18 15:14  初和  阅读(48)  评论(0)    收藏  举报