博客 / 詳情

返回

策略模式

策略是對算法的封裝,將不同的算法封裝到具有相同接口的獨立的類中,使算法本身和客户端分離開來,並且算法之間可以相互替換。

在策略模式中主要有以下幾種角色

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

當我們使用新的廠商的雲播報時我們只需要增加一個策略,然後再對應的集合中增加枚舉值即可,這樣對代碼的改動極小,符合開閉原則,並極大的解耦。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.