15.【設計模式.行爲型.策略模式】策略模式實現

【設計模式.行爲型.策略模式】

一、說明

策略模式封裝了不同的實現,可以基於不同的策略標識選擇不同的執行策略,從而避免書寫過多的if...else,switch等語句,擴展時不需要改動原代碼,只需要擴招不同的策略實現即可,符合開閉原則。常常搭配工廠模式一起使用。

一、最基本的策略模式使用

定義策略接口,實際執行的策略通過設置上下環境類的方式調用不同的策略。

package com.fatsea.news.pattern.behavioral;

/**
 * @Author: Chunhai.Hu
 * @Date: 2021/4/28 17:41
 * @Desc: 行爲型.策略模式
 * @最基本的策略模式使用
 */
public class BaseStrategyTest {
    public static void main(String[] args) {
        // 策略環境實例
        Context context = new Context();
        // 使用策略A
        IBaseStrategy baseStrategyA = new BaseStrategyA();
        context.setStrategy(baseStrategyA);
        baseStrategyA.strategyMethod();
        // 使用策略B
        IBaseStrategy baseStrategyB = new BaseStrategyB();
        context.setStrategy(baseStrategyB);
        baseStrategyB.strategyMethod();
    }
}

// 策略抽象
interface IBaseStrategy {
    void strategyMethod ();
}

// 具體策略類A
class BaseStrategyA implements IBaseStrategy {

    @Override
    public void strategyMethod() {
        System.out.println("aliPay支付策略......");
    }
}

// 具體策略類B
class BaseStrategyB implements IBaseStrategy {

    @Override
    public void strategyMethod() {
        System.out.println("weChatPay支付策略......");
    }
}

// 上下文環境類
class Context {
    private IBaseStrategy strategy;

    public Context() {
    }

    public Context(IBaseStrategy strategy) {
        this.strategy = strategy;
    }

    public void setStrategy(IBaseStrategy strategy) {
        this.strategy = strategy;
    }

    public void strategyMethod () {
        strategy.strategyMethod();
    }
}

二、促銷策略測試[策略+工廠+單例]

使用工廠模式初始化各個策略的單例,放入一個Map集合中,調用時根據標識獲取不同策略的實現執行。

package com.fatsea.news.pattern.behavioral;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: Chunhai.Hu
 * @Date: 2021/4/30 16:14
 * @Desc: 行爲型.策略模式.促銷策略測試[策略+工廠+單例]
 */
public class PromotionalStrategyTest {
    public static void main(String[] args) {
        // 使用工廠和枚舉類型調用
        IPromotional strategy = PromotionalStrategyFactory.getPromotionalStrategy(PromotionalStrategyFactory.PromotionalKey.COUPON);
        strategy.doPromotional();

        // 使用上下文環境類調用
        PromotionalActivity activity = new PromotionalActivity();
        activity.doPromotional();
    }
}

// 促銷抽象接口
interface IPromotional {
    void doPromotional();
}

// 促銷手段:無(默認方式)
class EmptyStrategy implements IPromotional {

    @Override
    public void doPromotional() {
        System.out.println("原價購買,無促銷手段");
    }
}

// 促銷手段:團購
class GroupByStrategy implements IPromotional {

    @Override
    public void doPromotional() {
        System.out.println("團購促銷.滿5人即可享受團購價");
    }
}

// 促銷手段:返現
class CashBackStrategy implements IPromotional {

    @Override
    public void doPromotional() {
        System.out.println("返現實付款的20%至付款賬戶");
    }
}

// 促銷手段:優惠券
class CouponStrategy implements IPromotional {

    @Override
    public void doPromotional() {
        System.out.println("使用優惠券抵扣");
    }
}

// 上下文環境類:具體活動[如需要.可將活動也進行抽象]
class PromotionalActivity {
    IPromotional strategy;

    // 默認使用無優惠策略
    public PromotionalActivity() {
        this.strategy = new EmptyStrategy();
    }

    public PromotionalActivity(IPromotional strategy) {
        this.strategy = strategy;
    }

    public void setStrategy(IPromotional strategy) {
        this.strategy = strategy;
    }

    public void doPromotional () {
        strategy.doPromotional();
    }
}

// 策略生成工廠
class PromotionalStrategyFactory {

    // 單例初始話所有促銷策略到PROMOTIONS中,或者使用初級工廠動態生成不同的Strategy
    private static Map<PromotionalKey, Object> PROMOTIONS = new HashMap<PromotionalKey, Object>();

    static {
        PROMOTIONS.put(PromotionalKey.EMPTY, new EmptyStrategy());
        PROMOTIONS.put(PromotionalKey.GROUPBY, new GroupByStrategy());
        PROMOTIONS.put(PromotionalKey.CASHBACK, new CashBackStrategy());
        PROMOTIONS.put(PromotionalKey.COUPON, new CouponStrategy());
    }

    // 默認爲public、static、final屬性
    enum PromotionalKey {
        EMPTY, GROUPBY, CASHBACK, COUPON
    }

    // 不傳時,採用無優惠策略
    public static IPromotional getPromotionalStrategy() {
        return (IPromotional) PROMOTIONS.get(PromotionalKey.EMPTY);
    }

    // 根據優惠標識獲取實際優惠策略
    public static IPromotional getPromotionalStrategy(PromotionalKey key) {
        return (IPromotional) PROMOTIONS.get(key);
    }
}

三、支付策略測試[策略+工廠+單例]

模式與二中的模式一致,只是用在了不同的業務場景,上述是優惠策略,這個是支付策略。

package com.fatsea.news.pattern.behavioral;

import lombok.Data;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: Chunhai.Hu
 * @Date: 2021/4/30 17:22
 * @Desc: 行爲型.策略模式.支付策略測試[策略+工廠+單例]
 */
public class PayStrategyTest {
    public static void main(String[] args) {
        // 生成訂單
        Order order = new Order();
        order.setTradeNo("JD079825648546845");
        order.setPrice(1000);
        order.setNum(5);

        // 使用工廠和枚舉類型調用支付策略
        IPayStrategy strategy = PayStrategyFactory.getPayStrategy(PayStrategyFactory.PayWay.GOOGLEPAY);
        System.out.println(strategy.getVoucher(order));
        System.out.println(strategy.verifyPayResult(order.getTradeNo()));
    }
}

// 訂單類
@Data
class Order {
    // 單號
    private String tradeNo;
    // 單價
    private Integer price;
    // 數量
    private Integer num;
}

// 支付策略抽象
interface IPayStrategy {

    // 獲取支付憑證,調起支付
    String getVoucher (Order order);

    // APP主動上報,校驗支付結果
    String verifyPayResult (String tradeNo);
}

// 支付策略:支付寶
class AliPay implements IPayStrategy {

    @Override
    public String getVoucher(Order order) {
        String result = "支付寶,訂單號:" + order.getTradeNo() +
                ",單價:" + order.getPrice() +
                ",數量:" + order.getNum() +
                ",總價:" + order.getPrice() * order.getNum();
        return result;
    }

    @Override
    public String verifyPayResult(String tradeNo) {
        return "支付寶支付成功,單號" + tradeNo;
    }
}

// 支付策略:微信支付
class WeChatPay implements IPayStrategy {

    @Override
    public String getVoucher(Order order) {
        String result = "微信支付,訂單號:" + order.getTradeNo() +
                ",單價:" + order.getPrice() +
                ",數量:" + order.getNum() +
                ",總價:" + order.getPrice() * order.getNum();
        return result;
    }

    @Override
    public String verifyPayResult(String tradeNo) {
        return "微信支付成功,單號" + tradeNo;
    }
}

// 支付策略:谷歌支付
class GooglePay implements IPayStrategy {

    @Override
    public String getVoucher(Order order) {
        String result = "谷歌支付,訂單號:" + order.getTradeNo() +
                ",單價:" + order.getPrice() +
                ",數量:" + order.getNum() +
                ",總價:" + order.getPrice() * order.getNum();
        return result;
    }

    @Override
    public String verifyPayResult(String tradeNo) {
        return "谷歌支付成功,單號" + tradeNo;
    }
}

// 支付策略生成工廠
class PayStrategyFactory {

    // 單例初始化所有支付策略
    private static Map<PayWay, IPayStrategy> payStrategyMap = new HashMap<PayWay, IPayStrategy>();

    static {
        payStrategyMap.put(PayWay.ALIPAY, new AliPay());
        payStrategyMap.put(PayWay.WECHATPAY, new WeChatPay());
        payStrategyMap.put(PayWay.GOOGLEPAY, new GooglePay());
    }

    // 默認爲public、static、final屬性
    enum PayWay {
        ALIPAY, WECHATPAY, GOOGLEPAY
    }

    // 默認使用支付寶
    public static IPayStrategy getPayStrategy () {
        return payStrategyMap.get(PayWay.ALIPAY);
    }

    // 根據PayWay返回不同的支付策略
    public static IPayStrategy getPayStrategy (PayWay payWay) {
        return payStrategyMap.get(payWay);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章