zoukankan      html  css  js  c++  java
  • Java封装商场打折策略(Strategy模式)

    有了OO的基础后,开始认真学习设计模式。

    首先学习的是Strategy,下面就封装商场打折策略来分析下策略模式是怎样一回事。

    商场每逢节假日都会对不同的商品采用不同的打折策略,首先卖苹果的说我的苹果要打折,好的,我们建立Market和Apple类。

     1 /**
     2  * 
     3  * @author LingJian
     4  *
     5  */
     6 public class Market {
     7 
     8     /**
     9      * 只对Apple
    10      * @param apple
    11      */
    12     public static void normalSell(Apple apple) {
    13         System.out.println("未打折价钱:" + apple.getPrice() * apple.getWeight());
    14     }
    15     /**
    16      * 只对Apple
    17      * @param apple
    18      */
    19     public static void discountSell(Apple apple) {
    20         double weight = apple.getWeight();
    21         //打折算法
    22         if(weight < 10) {
    23             normalSell(apple);
    24         }else if(weight >= 10 && weight < 50) {
    25             System.out.println("打八八折价钱:" + apple.getPrice() * apple.getWeight() * 0.88 );
    26         }else if(weight >= 50) {
    27             System.out.println("打五折价钱:" + apple.getPrice() * apple.getWeight() * 0.5 );
    28         }        
    29     }
    30 }
     1 /**
     2  * 
     3  * @author LingJian
     4  *
     5  */
     6 public class Apple {
     7     //重量
     8     private double weight;
     9     //单价 实际开发中 涉及金钱等精确计算都是用BigDecimal
    10     private double price;
    11         
    12     public double getWeight() {
    13         return weight;
    4     }
    15     public void setWeight(double weight) {
    16         this.weight = weight;
    17     }
    18     public double getPrice() {
    19         return price;
    20     }
    21     public void setPrice(double price) {
    22         this.price = price;
    23     }
    24     public Apple(double weight, double price) {
    25         super();
    26         this.weight = weight;
    27         this.price = price;
    28     }
    29 
    30 
    31     
    32 }
    /**
     * 
     * @author LingJian
     *
     */
    public class Test {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            //只能对苹果打折 还不能对通用的一类事物打折 而且都是要卖什么就写什么打折算法 其实每类事物打折算法又是不一致的
            Apple apple = new Apple(10.35, 3.6);
            Market.normalSell(apple);
            Market.discountSell(apple);
        }
    
    }

    节假日过了两天后,卖香蕉的一看,苹果打折促销后,原先买香蕉的都跑去买苹果了,不行,香蕉也要打折,不然卖不出去就烂了,OK,这个时候,我们再往Market加一个卖香蕉的打折方法和Banana类,问题很好的解决了….后来,卖梨卖橙子卖橘子的都来了,但是由于每个商品打折的算法和策略都不一样,咱们只能先往Market不停的加方法….显然这不是很好的设计,不停的写打折方法就说明我们这个打折方法不够通用,扩展性不强,那这个时候怎么办呢?对,肯定是想办法让咱们的打折方法通用,增强扩展性,那么说到扩展我们肯定得想到OO的核心-多态。

    这里,我们创建一个Discountable接口,让需要打折的商品都实现这个接口,并且在重写打折方法,这样对于Market来说,我们就把具体的打折实现方式都交给了具体的对象本身来实现,我们就不用担心算法策略不同而不停的增加方法。

    /**
     * 
     * @author LingJian
     *
     */
    public class Market {
    
    
    
        /**
         * 对可打折的一类事物进行打折
         * @param apple
         */
        public static void discountSell(Discountable d) {
            d.discountSell();
        }
        
        
    }
    public class Apple implements Discountable {
        //重量
        private double weight;
        //单价 实际开发中 涉及金钱等精确计算都是用BigDecimal
        private double price;
            
        public double getWeight() {
            return weight;
        }
        public void setWeight(double weight) {
            this.weight = weight;
        }
        public double getPrice() {
            return price;
        }
        public void setPrice(double price) {
            this.price = price;
        }
        public Apple(double weight, double price) {
            super();
            this.weight = weight;
            this.price = price;
        }
        
        @Override
        public void discountSell() {
            //打折算法
            if(weight < 10) {
                System.out.println("Apple未打折价钱:" + weight * price);
            }else if(weight >= 10 && weight < 50) {
                System.out.println("Apple打八八折价钱:" + weight * price * 0.88 );
            }else if(weight >= 50) {
                System.out.println("Apple打五折价钱:" + weight * price * 0.5 );
            }
        }
        
        
    }
    /**
     * 
     * @author LingJian
     *
     */
    public class Banana implements Discountable {
        //重量
        private double weight;
        //单价 实际开发中 涉及金钱等精确计算都是用BigDecimal
        private double price;
        
        public double getWeight() {
            return weight;
        }
        public void setWeight(double weight) {
            this.weight = weight;
        }
        public double getPrice() {
            return price;
        }
        public void setPrice(double price) {
            this.price = price;
        }
        public Banana(double weight, double price) {
            super();
            this.weight = weight;
            this.price = price;
        }
        
        @Override
        public void discountSell() {
            //打折算法
            if(weight < 5) {
                System.out.println("Banana未打折价钱:" + weight * price);
            }else if(weight >= 5 && weight < 10) {
                System.out.println("Banana打八八折价钱:" + weight * price * 0.88 );
            }else if(weight >= 10) {
                System.out.println("Banana打五折价钱:" + weight * price * 0.5 );
            }        
        }
    
    }
    /**
     * 
     * @author LingJian
     *
     */
    public interface Discountable {
        public void discountSell();
    }
    /**
     * 
     * @author LingJian
     *
     */
    public class Test {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            //可对打折一类事物进行打折啦 先是Apple
            Discountable d = new Apple(10.35, 3.6);
    //        Discountable d = new Banana(10.35, 1.6);
            Market.discountSell(d);
        }
    
    }

    OK,这一次咱们采用的都是固定的按购买量打折,但是打折的策略算法是有可能变化的,不一定每次节假日都是按购买量打折,所以咱们的打折策略不能写死了,得能够灵活的变化,怎么办呢?当然,还是多态,我们再创建一个Discountor接口,而具体的打折策略都交给具体的实现类来实现,再在需要打折的商品类中,让其持有Discountor接口的实现子类,这样不管每次打折策略怎么变化,我们只需要让打折商品持有不同的实现对象即可灵活的应对变化,这就是策略(Strategy)模式。

    /**
     * 
     * @author LingJian
     *
     */
    public class Apple implements Discountable {
        //重量
        private double weight;
        //单价 实际开发中 涉及金钱等精确计算都是用BigDecimal
        private double price;
        //按购买量打折
    //    private Discountor d = new AppleWeightDiscountor();
        //按购买总价打折
        private Discountor d = new ApplePriceDiscountor();
        
        public double getWeight() {
            return weight;
        }
        public void setWeight(double weight) {
            this.weight = weight;
        }
        public double getPrice() {
            return price;
        }
        public void setPrice(double price) {
            this.price = price;
        }
        public Apple(double weight, double price) {
            super();
            this.weight = weight;
            this.price = price;
        }
        
        @Override
        public void discountSell() {
            d.discount(this);
        }
        
        
    }
    /**
     * 
     * @author LingJian
     *
     */
    public interface Discountor {
        public void discount(Discountable d);
    }
    /**
     * 
     * @author LingJian
     *
     */
    public class AppleWeightDiscountor implements Discountor {
    
        /**
         * 按购买量打折
         */
        @Override
        public void discount(Discountable d) {
            Apple apple = (Apple)d;
            if(apple.getWeight() < 10) {
                System.out.println("Apple未打折价钱:" + apple.getWeight() * apple.getPrice());
            }else if(apple.getWeight() >= 10 && apple.getWeight() < 50) {
                System.out.println("Apple打八八折价钱:" + apple.getWeight() * apple.getPrice() * 0.88 );
            }else if(apple.getWeight() >= 50) {
                System.out.println("Apple打五折价钱:" + apple.getWeight() * apple.getPrice() * 0.5 );
            }        
        }
    
    }
    /**
     * 
     * @author LingJian
     *
     */
    public class ApplePriceDiscountor implements Discountor {
    
        /**
         * 购买满10元立减1角
         * 购买满20元立减1元
         * 购买满30元立减5元
         */
        @Override
        public void discount(Discountable d) {
            Apple apple = (Apple)d;
            if(apple.getWeight() * apple.getPrice() < 10) {
                System.out.println("Apple未打折价钱:" + apple.getWeight() * apple.getPrice());
            }else if(apple.getWeight() * apple.getPrice() >= 10 && apple.getWeight() * apple.getPrice() < 20) {
                System.out.println("Apple购买满10元立减1角:" + (apple.getWeight() * apple.getPrice() - 0.1) );
            }else if(apple.getWeight() * apple.getPrice() >= 20 && apple.getWeight() * apple.getPrice() < 30) {
                System.out.println("Apple购买满20元立减1元:" + (apple.getWeight() * apple.getPrice() - 1) );
            }else if(apple.getWeight() * apple.getPrice() >= 30) {
                System.out.println("Apple购买满30元立减5元:" + (apple.getWeight() * apple.getPrice() - 5) );
            }        
        }
    
    }

    Test类无需改变。

    简单的描绘下封装商场打折策略的设计图。如下所示:

                           

    Market负责给Discountable的商品打折,而具体的可打折的商品的打折的算法则交给Discountor的实现子类来具体实现。

  • 相关阅读:
    Optional int parameter 'resourceState' is present but cannot be translated into a null value
    创建第一个react项目
    后台接收参数报错 Required String parameter 'id' is not present
    sql查询条件参数为空
    斐波那契数列
    Map获取key值
    Java8之集合排序
    Android学习笔记(4)----Rendering Problems(The graphics preview in the layout editor may not be accurate)
    LeetCode赛题395----Longest Substring with At Least K Repeating Characters
    LeetCode赛题394----Decode String
  • 原文地址:https://www.cnblogs.com/iou123lg/p/2991981.html
Copyright © 2011-2022 走看看