策略是对算法的封装,将不同的算法封装到具备雷同接口的独立的类中,使算法自身和客户端拆散开来,并且算法之间能够互相替换。
在策略模式中次要有以下几种角色
- 上下文信息类(Context):用于寄存和执行须要应用的具体策略类以及客户端调用的逻辑。
- 形象策略类(Strategy):定义策略的共有办法。
- 具体策略类(ConcreteStrategy 等):实现形象策略类定义的共有办法。
上面应用策略模式模仿一个我开发过程中的一个场景,在聚合领取中商户常常会绑定一些专门用于领取播报的盒子,咱们称它为云播报,这些云播报可能是不同厂商生产的,咱们进行告诉的时候因为厂商之间给的接口和调用形式也不同,所以咱们把云播报告诉形象为一个形象策略,而每个具体厂商就是一个具体策略。
形象策略
public interface CloudHornStrategy { /** * 发送音讯 * @param body * @return */ boolean sendMessage(CloudRequestBody body);}
参数类
public class CloudRequestBody { private static Map<Integer,String> channelMap = new HashMap<>(); static { channelMap.put(1,"支付宝"); channelMap.put(2,"微信"); channelMap.put(3,"云闪付"); channelMap.put(4,"数字人民币"); } /** * 金额 */ private Long money; /** * 通道 */ private String channel; public CloudRequestBody(Long money,int channel) { this.money = money; this.channel = channelMap.get(channel); } public Long getMoney() { return money; } public String getChannel() { return channel; }}
具体策略
public class LDCloudHornStrategy implements CloudHornStrategy{ @Override public boolean sendMessage(CloudRequestBody body) { //..... //一些列组装参数,数据处理,调用厂商接口 String msg = String.format("LD厂商推送:%s到账%d元", body.getChannel(), body.getMoney()); System.out.println(msg); return true; }}
@Override public boolean sendMessage(CloudRequestBody body) { //..... //一些列组装参数,数据处理,调用厂商接口 String msg = String.format("TY厂商推送:%s到账%d元", body.getChannel(), body.getMoney()); System.out.println(msg); return true; }}
告诉上下文
public class PayNotifyContext { private static Map<String,CloudHornStrategy> strategyMap = null; static { strategyMap = new HashMap<>(); strategyMap.put("LD",new LDCloudHornStrategy()); strategyMap.put("TY",new TYCloudHornStrategy()); } private CloudHornStrategy strategy; public PayNotifyContext(String horn) { this.strategy = strategyMap.get(horn); } public void payNotify(CloudRequestBody body){ strategy.sendMessage(body); }}
领取客户端告诉
public class PayClient { public static void main(String[] args) { //领取胜利,回调告诉接口 //获取用户绑定了几个云播报别离是什么类型 //比如说用户有三个云播报....当然获取的用户数据不可能只有用户用的云播报品牌,其它用户信息咱们暂且不论 String[] horns = new String[]{"TY","LD","LD"}; //假如领取了误元 CloudRequestBody body = new CloudRequestBody(5L,1); for (String horn:horns) { new PayNotifyContext(horn).payNotify(body); } }}=====后果=====TY厂商推送:支付宝到账5元LD厂商推送:支付宝到账5元LD厂商推送:支付宝到账5元
当咱们应用新的厂商的云播报时咱们只须要减少一个策略,而后再对应的汇合中减少枚举值即可,这样对代码的改变极小,合乎开闭准则,并极大的解耦。