一、什么是策略模式
策略这个词怎么理解,打个比方,出门选择的交通工具,汽车,自行车,火车,等交通工具。而使用交通工具出门,每一种都属于一种策略。
在比如我们我们办公,有使用mac,windwos,ios ,安卓等等系统,每种系统的使用都是一种策略,我们可以随时的切换 互相替换。比如我今天使用windows电脑办公,明天使用mac办公。
策略模式(strategy),每个策略定义了一组算法,或者可以理解为行为。但是最终目的都是一样的。
图中,Context是容器 ,strategy是策略接口(或抽象类),用来定义支持算法(方法)的公共接口;ConcreateStrategy是策略接口的具体实现类,实现了Strategy接口方法的具体逻辑。
1.Context上下文对象
Context上下文对象,也叫上下文对象(容器,相当于一个Map,用来存储策略对象的引用),起承上启下的作用,用来获取不同的策略,
在java中利用多态机制完成。用父类接收其子类,实现不同策略之间的切换。
例如:
2.策略模式的应用场景
1.联合登陆,qq,wx,钉钉。
2.支付方式 支付宝,微信,云闪付,银联。
4.快递 申通,圆通,京东,德邦等等
5.发送通知,短信,公众号,钉钉,邮件。
根据用户选用的登陆方式,支付方式等等,来调用不同的策略。相同的事情,调用的渠道不通,都可以使用策略模式
3.聚合支付平台
搭建聚合支付平台,需要调用到很多的第三方支付接口,比如支付宝,微信,小米支付等,而这些支付平台的对接方式都是相同的,如果通过传统的if判断进行接口的调用,后期的维护性极差。这时候我们就可以使用到策略模式
这时候就可以使用到策略模式来解决多重if判断
公共的支付接口
public interface PayStrategy {
/**
* 共同算法实现骨架 (可以使用接口或者抽象类)
*
* @return
*/
String toPayHtml();
}
package com.mayiakt.strategy.impl;
public class AliPayStrategy implements PayStrategy {
@Override
public String toPayHtml() {
return "对接支付宝接口";
}
}
public class UnionPayStrategy implements PayStrategy {
@Override
public String toPayHtml() {
return "对接银联支付";
}
}
public class WeChatPayStrategy implements PayStrategy {
@Override
public String toPayHtml() {
return "对接微信支付";
}
}
factory
@Slf4j
public class StrategyFactory {
/**
* 存放所有的PayStrategy key为PayStrategy别名 value是PayStrategy
*/
private static Map<String, PayStrategy> payStrategys = new HashMap<>();
public StrategyFactory() {
initStrategy();
}
public static void initStrategy() {
payStrategys.put("aliPayStrategy", new AliPayStrategy());
payStrategys.put("unionPayStrategy", new UnionPayStrategy());
payStrategys.put("weChatPayStrategy", new WeChatPayStrategy());
log.info("<初始化支付相关策略ok,payStrategys:{}>", payStrategys);
}
public static PayStrategy getPayStrategy(String strategyType) {
return payStrategys.get(strategyType);
}
}
controlelr
@RestController
public class PayContextService {
private StrategyFactory strategyFactory = new StrategyFactory();
@RequestMapping("/toPayHtml")
public String toPayHtml(String payCode) {
if (StringUtils.isEmpty(payCode)) {
return "payCode is null";
}
//根据payCode名称从 StrategyFactory获取具体 Strategy策略
PayStrategy payStrategy = strategyFactory.getPayStrategy(payCode);
if (payStrategy == null) {
return "not found payStrategy";
}
//获取到具体的payStrategy 调用toPayHtml
return payStrategy.toPayHtml();
}
}
策略模式中最核心 容器(map集合) map集合底层简化了我们多重if判断 在通过多态策略
找到具体实现类方法调用。
在spring项目中我们是没有必要单独定义我们容器 因为spring ioc 自带容器。