美文网首页
设计模式——策略模式

设计模式——策略模式

作者: prik丶 | 来源:发表于2019-07-18 17:17 被阅读0次

    《Head First 设计模式》 学习笔记
    码云同步更新中
    如有错误或不足之处,请一定指出,谢谢~

    目录

    查看其它设计模式笔记,点这里→设计模式笔记汇总

    策略模式

    • 定义:
      • 策略模式——定义算法族,分别封装起来,让他们可以互相替换,此模式让算法的变化独立与使用算法的客户
    • 适用范围:
      • 几个类的主要逻辑相同,只在部分逻辑的算法和行为上稍有区别的情况
      • 有几种相似的行为(算法),客户端需要动态决定使用哪一种
    • 优点:
      • 动态改变对象的行为
      • 扩展性良好
    • 缺点:
      • 客户端必须知道所有的策略类,并自行决定使用哪一个
      • 会产生很多策略类
      • 只适合扁平的结构,策略之间层级平等,不能互相嵌套
    • 设计原则:
      • 找出应用中可能需要变化的地方,把它们独立出来,不要和那些不需要变化的代码混在一起
      • 针对接口编程,而不是针对实现编程
      • 多用组合,少用继承
    • 结构
      • 抽象策略:抽象类或接口,约束具体策略的行为
      • 具体策略:抽象策略的实现
      • 上下文类:负责具体交互,相当于一个容器,持有具体策略实现的引用
    • 执行顺序:
      • 创建具体策略实现
      • 创建上下文类,并注入策略
      • 通过上下文类处理数据
    • 案例
      • 电子商城,客户下单时需要根据不同的客户类型计算折扣后价格
        • 普通客户:无优惠
        • vip客户:9折
        • 其他自定义策略...
      • 还用到了工厂模式,工厂类用到了单例模式,达到消除if/else语句的目的
    • 代码
    /**
     * 策略接口
     *
     * @author Xushiwei
     * @date 2019/7/18
     */
    public interface DiscountStrategy {
    
        /**
         * 计算折扣后价格
         *
         * @param originalPrice 原价
         * @return 折扣后应付价格
         */
        BigDecimal calDiscountPrice(BigDecimal originalPrice);
    }
    
    /**
     * 普通客户策略实现
     *
     * @author Xushiwei
     * @date 2019/7/18
     */
    public class OrdinaryDiscountStrategy implements DiscountStrategy {
        @Override
        public BigDecimal calDiscountPrice(BigDecimal originalPrice) {
            System.out.println("普通客户,无优惠");
            return originalPrice;
        }
    }
    
    /**
     * vip客户策略实现,九折
     *
     * @author Xushiwei
     * @date 2019/7/18
     */
    public class VipDiscountStrategy implements DiscountStrategy {
        @Override
        public BigDecimal calDiscountPrice(BigDecimal originalPrice) {
            System.out.println("VIP客户,九折优惠~");
            return originalPrice.multiply(new BigDecimal("0.9"));
        }
    }
    
    /**
     * 顾客
     * 注:@Data为lombok注解
     *
     * @author Xushiwei
     * @date 2019/7/18
     */
    @Data
    public class Customer {
    
        /**
         * 姓名
         */
        private String name;
    
        /**
         * 客户类型
         */
        private Integer type;
    
        /**
         * 普通客户
         */
        public static final int TYPE_ORDINARY = 1;
        /**
         * vip客户
         */
        public static final int TYPE_VIP = 2;
        /**
         * 合作伙伴
         */
        public static final int TYPE_PARTNER = 3;
    }
    
    /**
     * 策略工厂
     * 单例
     *
     * @author Xushiwei
     * @date 2019/7/18
     */
    public class DiscountStrategyFactory {
    
        /**
         * private修饰的构造函数,防止使用者手动创建
         */
        private DiscountStrategyFactory() {
        }
    
        private static DiscountStrategyFactory factory = new DiscountStrategyFactory();
    
        private static Map<Integer, DiscountStrategy> strategyMap = new HashMap();
    
        static{
            strategyMap.put(Customer.TYPE_ORDINARY, new OrdinaryDiscountStrategy());
            strategyMap.put(Customer.TYPE_VIP, new VipDiscountStrategy());
            strategyMap.put(Customer.TYPE_PARTNER, new PartnerDiscountStrategy());
        }
    
        public DiscountStrategy creator(int customerType) {
            return strategyMap.get(customerType);
        }
    
        public static DiscountStrategyFactory getInstance() {
            return factory;
        }
    }
    
    /**
     * 上下文类
     *
     * @author Xushiwei
     * @date 2019/7/18
     */
    public class DiscountContext {
        private static DiscountStrategyFactory strategyFactory = DiscountStrategyFactory.getInstance();
        
        public BigDecimal calDiscountPrice(BigDecimal originalPrice, int customerType) {
            DiscountStrategy strategy = strategyFactory.creator(customerType);
            return strategy.calDiscountPrice(originalPrice);
        }
    }
    
    /**
     * 测试类
     *
     * @author Xushiwei
     * @date 2019/7/18
     */
    public class Test {
        public static void main(String[] args) {
            BigDecimal originalPrice = new BigDecimal(100);
    
            // 普通客户
            DiscountContext discountContext = new DiscountContext();
            BigDecimal price1 = discountContext.calDiscountPrice(originalPrice, 1);
    
            System.out.println("普通客户下单,原价:" + originalPrice + "元,应付款:" + price1 + "元");
    
            // vip客户
            BigDecimal price2 = discountContext.calDiscountPrice(originalPrice, 2);
            System.out.println("vip客户下单,原价:" + originalPrice + "元,应付款:" + price2 + "元");
        }
    }
    
    执行结果:
        普通客户,无优惠
        普通客户下单,原价:100元,应付款:100元
        VIP客户,九折优惠~
        vip客户下单,原价:100元,应付款:90.0元
    

    相关文章

      网友评论

          本文标题:设计模式——策略模式

          本文链接:https://www.haomeiwen.com/subject/zkfrlctx.html