設(shè)計(jì)模式之策略模式實(shí)際操作

背景
? ?最近新開了一個(gè)項(xiàng)目,總的作用是風(fēng)控場(chǎng)景下,不同的用戶策略,計(jì)算不同的指標(biāo)類型。所以使用策略模式進(jìn)行實(shí)現(xiàn)。
????原來使用策略模式會(huì)遇到一個(gè)問題,就是對(duì)應(yīng)的策略實(shí)現(xiàn)類中使用Bean會(huì)為空。
????例如:

????原來比較簡(jiǎn)單粗暴的方式是將這個(gè)類作為參數(shù)傳入,但是在公用同一個(gè)計(jì)算接口的情況下,不符合現(xiàn)有的要求。
????所以采用springContext實(shí)現(xiàn)。
實(shí)現(xiàn)邏輯


代碼
策略DTO
@Data
public class RiskDTO {
? ?private RiskVariableEnums riskVariableType;
? ?private String consumerNo;
? ?public RiskVariableEnums getRiskType() {
? ? ? ?return riskVariableType;
? ?}
? ?public String getConsumerNo() {
? ? ? ?return consumerNo;
? ?}
? ?public void setRiskVariableType(RiskVariableEnums riskVariableType) {
? ? ? ?this.riskVariableType = riskVariableType;
? ?}
}
策略抽象接口
/**
* @author yanghong
*/
public interface RiskVariableStrategy {
? ?/**
? ? * 策略計(jì)算
? ? * @param consumerNo 用戶編號(hào)
? ? * @return 計(jì)算后返回的數(shù)據(jù)
? ? */
? ?public <T> T cal(String consumerNo);
? ?/**
? ? * @return
? ? */
? ?RiskVariableEnums applyRiskType();
}
策略實(shí)現(xiàn)類ContactCnEnCntStrategy
/**
* @author yanghong
*/
@Service
public class ContactCnEnCntStrategy implements RiskVariableStrategy{
? ?@Autowired
? ?private RisktUserPhoneBookService risktUserPhoneBookService;
? ?@Override
? ?public <T> T cal(String customerNo) {
? ? ? ?List<RisktUserPhoneBook> books = risktUserPhoneBookService.getUserPhoneBookList(customerNo);
? ? ? ?if (books.isEmpty()) {
? ? ? ? ? ?return null;
? ? ? ?}
? ? ? ?return (T) Integer.valueOf(books.size());
? ?}
? ?@Override
? ?public RiskVariableEnums applyRiskType() {
? ? ? ?return RiskVariableEnums.CON_CN_EN_CNT;
? ?}
}
策略上下文RiskVariableStrategyContext
@Component
public class RiskVariableStrategyContext implements ApplicationContextAware {
? ?private static Map<String, RiskVariableStrategy> riskVariableStrategyMap;
? ?/**
? ? * 策略上下文對(duì)象委派具體的策略執(zhí)行
? ? * @param riskDTO
? ? * @return
? ? */
? ?public static Object riskHandler(RiskDTO riskDTO) {
? ? ? ?return getRIskStrategy(riskDTO.getRiskType()).cal(riskDTO.getConsumerNo());
? ?}
? ?/**
? ? * 獲取適用的策略
? ? * @param riskType
? ? * @return
? ? */
? ?private static RiskVariableStrategy getRIskStrategy(RiskVariableEnums riskType) {
? ? ? ?RiskVariableStrategy strategy = riskVariableStrategyMap.get(riskType.name());
? ? ? ?return Optional.ofNullable(strategy)
? ? ? ? ? ? ? ?.orElseThrow(() -> new RuntimeException(String.format("not found coupon type strategy , coupon type is %s", riskType.getCode())));
? ?}
? ?@Override
? ?public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
? ? ? ?Map<String, RiskVariableStrategy> strategyBeans = applicationContext.getBeansOfType(RiskVariableStrategy.class);
? ? ? ?if (strategyBeans == null || strategyBeans.size() == 0) {
? ? ? ? ? ?// 無(wú)可用的優(yōu)惠券策略
? ? ? ? ? ?return;
? ? ? ?}
? ? ? ?riskVariableStrategyMap = new HashMap<>(strategyBeans.size());
? ? ? ?for (RiskVariableStrategy strategy : strategyBeans.values()) {
? ? ? ? ? ?riskVariableStrategyMap.put(strategy.applyRiskType().name(), strategy);
? ? ? ? ? ?System.out.println("register strategy " + strategy.applyRiskType());
? ? ? ?}
? ?}
}
策略使用Controller
public String linfentong(@RequestBody @Valid LinfentongRequest request) {
? ?RiskDTO riskDTO = new RiskDTO();
? ?riskDTO.setConsumerNo(request.getConsumerNo());
? ?switch (request.getVariableType()) {
? ? ? ?case "contact_blacklist_cnt":
? ? ? ? ? ?riskDTO.setRiskVariableType(RiskVariableEnums.CON_B_CNT);
? ? ? ? ? ?break;
? ? ? ?case "contact_cn_en_cnt":
? ? ? ? ? ?riskDTO.setRiskVariableType(RiskVariableEnums.CON_CN_EN_CNT);
? ? ? ? ? ?break;
? ? ? ?case "c_d180_callinout_black_count":
? ? ? ? ? ?riskDTO.setRiskVariableType(RiskVariableEnums.C_D180_CALL_BLACK_OUT_CNT);
? ? ? ? ? ?break;
? ? ? ?case "c_d90_callinout_morning_count":
? ? ? ? ? ?riskDTO.setRiskVariableType(RiskVariableEnums.C_D90_CALL_MORNING_CNT);
? ? ? ? ? ?break;
? ? ? ?case "c_d30_middle_pd":
? ? ? ? ? ?riskDTO.setRiskVariableType(RiskVariableEnums.C_D30_MID_PD);
? ? ? ? ? ?break;
? ? ? ?case "c_d1_callout_morning_duration_avg":
? ? ? ? ? ?riskDTO.setRiskVariableType(RiskVariableEnums.C_D1_CALL_MORNING_DUR_AVG);
? ? ? ? ? ?break;
? ? ? ?default:
? ? ? ? ? ?break;
? ?}
? ?return JSON.toJSONString(RiskVariableStrategyContext.riskHandler(riskDTO));
}