策略模式

策略是对算法的封装,将不同的算法封装到具有相同接口的独立的类中,使算法本身和客户端分离开来,并且算法之间可以相互替换。

在策略模式中主要有以下几种角色

  • 上下文信息类(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元 

当我们使用新的厂商的云播报时我们只需要增加一个策略,然后再对应的集合中增加枚举值即可,这样对代码的改动极小,符合开闭原则,并极大的解耦。

发表评论

相关文章