• 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);
        }
    }
    
  • 相关阅读:
    [官网]CREATE EXTENSION PostGreSQL 创建函数的方法
    Notepad++的一个用法 转换为unix 格式的文件
    LLVM的安装
    Linux 下面RPM 安装的SQLSERVER 修改字符集的方法
    Linux 下面 Sqlserver 2017 的简单安装
    Linux下面将windows写的脚本转换成 Linux 格式的文件
    PostgreSQL 安装了contrib 之后 登录失败的问题
    Linux 下面 PG 的 uuid-ossp 包安装办法
    Chrome 离线安装插件的办法
    [新三板摘牌]国资企业济南华光光电去年终止拟IPO今年摘牌新三板
  • 原文地址:https://www.cnblogs.com/Nick-Hu/p/14723025.html
Copyright © 2020-2023  润新知