浅谈策略模式的使用

1.写在前面

前段时间,和同事共同开发一个关于保险继续率的需求。简单来讲,就是根据数据库中的保单数据从省、公司、产品、人等不同维度计算继续率数据并落库。需求并不复杂,实现一开始想的就是定时任务去跑数,然后去根据不同维度做一个标识,去计算不同的数据,插入数据库。

当然,首当其冲想到的是策略模式。毕竟if else 或者是 switch 都感觉太冗余,而且并不好扩展。

2.代码实现

首先定义策略接口类

public interface Strategy {

    /**
     * 判断当前执行策略的具体实现类
     *
     * @return
     */
    String getName();

    /**
     * 执行策略
     */
    void excutor();
}

实现类A 、 B

@Service
public class StrategyA implements Strategy {
    @Override
    public String getName() {
        return "strategyA";
    }
    @Override
    public void excutor() {
        System.out.println("strategyA");
    }
}


@Service
public class StrategyB implements Strategy {

    @Override
    public String getName() {
        return "strategyB";
    }

    @Override
    public void excutor() {
        System.out.println("strategyB");
    }
}

这样在想要去调用策略的地方去通过注入map,然后直接去get使用就可以

// 注入
@Autowired
private Map<String,Strategy> strategyMap ;


......

// 使用
public void cusumer(Map<String,String> params){
    // 省略校验和其他逻辑代码 ... 
    Strategy stg = strategyMap.get(params.get("flag"));
    if(null != stg){
        stg.execute();
    }
}

这样虽然可以实现在实际调用的时候选到合适的策略类,但是只要是需要使用策略的时候,都需要注入这个map,显得比较麻烦,于是进行了改进。

@Component
public class StrategyMap {
    public static Map<String, Strategy> MAP = new HashMap<>();

    /**
     * 可以通过这种对静态属性进行赋值
     *
     * @param list
     */
    @Autowired
    public void setPartnerService(List<Strategy> list) {
        list.forEach(item -> MAP.put(item.getName(), item));
    }

这样调用方可以直接通过

StrategyMap.MAP.get("strategyB").execute();
// 需要注意npe

去实现调用。

当然,我们可以将调用逻辑进行封装,让StrategyMap去承担调用,这样就不需要处处都去处理npe问题,代码如下

// StrategyMap 中增加方法

/**
 * 执行
 *
 * @param name
 */

public static void excutor(String name) {
    Optional.ofNullable(MAP.get(name)).ifPresent(item -> item.excutor());
}

......

// 调用端
StrategyMap.excutor("strategyB");

最后引入责任链模式:

// StrategyMap 中增加属性LIST
public static final List<Strategy> LIST = new ArrayList();
/**
 * 责任链模式
 *
 * @param name
 */
public static void excutor2(String name) {
    LIST.stream().filter(item -> item.getName().equals(name)).findFirst().get().excutor();
}

......

// 调用端
StrategyMap.excutor2("strategyB");
  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值