谈谈项目中的策略模式

文章目录

    • 概要
    • 业务背景
    • 代码细节
    • 小结

概要

策略模式(Strategy Pattern)属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
其主要目的是通过定义相似的算法,替换if else 语句写法,并且可以随时相互替换。

昨天和前端联调,去debug解决问题的时候,看见别人的代码里用到了设计模式,遂决定总结输出一下,毕竟学会了就是自己写的啦!

业务背景

在我们的客服系统中有一个板块是关于售后单的处理,我们对于售后单有如下操作:分配、同意、拒绝、跟进等。

在策略模式中,我们为这些方法提供了统一的入口,根绝前端传过来的策略枚举,我们能够去找到对应的策略实现。
谈谈项目中的策略模式_第1张图片

代码细节

关于策略模式的基本demo网上有很多这里就不再赘述。不了解的同学也可以先看看这篇策略模式详解

前端为我们提供一个策略选择,比如“分配”,那么在传过来的body中便会带上“assign”这个,根据此我们可以在后端中找到对应的实现,关于字符串到具体实现类的映射我们可以用一个map保存。在上面我分享的文章当中,作者提到一种方案采用static静态代码块,个人认为这种方案的缺陷,如果我新增了一个策略实现,那么我还得在静态代码块中添加相应映射,同时作者还提供了交由spring创建的方式。

无独有偶,在我们的项目中,也是采用了spring创建的方式,不过具体实现略有不同

static {
        payStrategies.put(PayTypeEnum.WX, new WxPayment());
        payStrategies.put(PayTypeEnum.ALIPAY, new AlipayPayment());
        payStrategies.put(PayTypeEnum.BANK_CARD, new BankCardPayment());
    }

可以看到,我们将RefundOperateContext这个类交由spring去管理,那么在项目启动初始化时,spring会去调用此类的构造函数。可是这里的入参Map strategyMap是从哪里获取的呢

@Service
public class RefundOperateContext {

    private final Map<String, RefundStrategy> strategyMap = new ConcurrentHashMap<>();

    public RefundOperateContext(Map<String, RefundStrategy> strategyMap) {
        this.strategyMap.clear();
        strategyMap.forEach((k, v) -> this.strategyMap.put(k, v));
    }

    public boolean handle(String poolId, AfterSaleOrderOperateSO afterSaleOrderOperateSO) {
        return strategyMap.get(poolId).strategy(afterSaleOrderOperateSO);
    }

}

秘密便在于这里,DefaultListableBeanFactory中的findAutowireCandidates会查找匹配Spring容器中的所有同类型Bean实例,也就是我们提供的策略接口的所有实现都会匹配到。
谈谈项目中的策略模式_第2张图片
BeanFactoryUtils.beanNamesForTypeIncludingAncestors可以拿到一个beanName数组,通过遍历数组就能拿到对应的策略接口的实现引用。

小结

很久没输出文章,最近几个月一直在实习,马上就要回校了也就空下来了,后续可能会补上一些在实习过程碰到的问题,希望后面一切顺利吧!

你可能感兴趣的:(spring,策略模式)