2.【设计模式.行为型.策略模式】策略模式实现

【设计模式.行为型.策略模式】

一、说明

策略模式封装了不同的实现,可以基于不同的策略标识选择不同的执行策略,从而避免书写过多的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);
    }
}
posted @ 2021-04-30 18:26  想~(●—●)肥~  阅读(62)  评论(0编辑  收藏  举报