zoukankan      html  css  js  c++  java
  • 小看--策略模式

         (一)什么是策略模式

              定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们可以相互替换,让算法独立于使用它的客户而独立变化。(这个在目前看来是句废话),接下来,通过了解策略模式的应用场景,大家就会明白策略模式了。

         (二)策略模式的演变

             场景,我们在做菜品促销的时候,通常都有9折,8折,7折,或者联合打折。

     Console.WriteLine("........学习策略模式.........");
                double goodsPrice = 100.00;
                double discountPrice = 0.0; ;
                while (true){
                    Console.WriteLine("请输入商品折扣");
                    int discount =Convert.ToInt32(Console.ReadLine());
                    //假设有9折,8折,7折
                    switch (discount){
                        case 7:
                            //打七折的时候,要多加十块
                            discountPrice = goodsPrice * 0.7 + 10;
                            break;
                        case 8:
                            //打八折的时候,要多加十块
                            discountPrice = goodsPrice * 0.8 + 8;
                            break;
                        case 9:
                            //打七折的时候,要多加十块
                            discountPrice = goodsPrice * 0.9 + 5;
                            break;
                    }
                    Console.WriteLine($"打折后总价为:{discountPrice}");

           可能一开始,我们大部分同学都会像我上面这么干,用一个SwitchCase就搞定了不同折扣之间的关系,但是我们觉得我们这样做好不好呢,如果我们现在要增加一个打六折的东西,那又来改上端代码,这种做法呢,是属于面向过程的,完全没有体会到面向对象的思想,那么我们就应该多想一点,想深入一点,那该怎么做呢,可能有的同学就会想了,进行一个抽象(封装类,屏蔽细节)。

        所以接下来就有了我们这个版本的:

     while (true) {
                    Console.WriteLine("请输入商品折扣");
                    int discount = Convert.ToInt32(Console.ReadLine());
                    IStrategy gy = null;
                    //假设有9折,8折,7折
                    switch (discount) {
                        case 7:
                            //打七折的时候,要多加十块
                            //discountPrice = goodsPrice * 0.7 + 10;
                            gy=new Seven();
                            break;
                        case 8:
                            //打八折的时候,要多加十块
                            //discountPrice = goodsPrice * 0.8 + 8;
                            gy = new Eight();
                            break;
                        case 9:
                            //打七折的时候,要多加十块
                            //discountPrice = goodsPrice * 0.9 + 5;
                            gy = new Night();
                            break;
                    }
                    Console.WriteLine($"打折后总价为:{gy.GetDiscountPrice(100)}");  //这个100是商品的原价
    
                }

          这个版本的改进:主要是我们把之前的打折的方法,都分别封装到类里面,然后实现了这些类都实现了IStratgy接口(如下图所示);,所以我们的代码改成了上面这个结构。

         

        到了这里,我们都要明白我们已经做到了开放抽象给上端了,上端是不依赖具体的细节了。

        我们继续,我们发现现在上端需要做的事情,1、接收用户的的输入选择相应的算法,2、执行相应的算法。

       

            在这里,我们这个例子中,执行算法,可能是比较简单一点,这里需要大家有点想像一下,我们实际中的,算法执行,可能非常复杂,可能需要进行写日志呀,根据不同的会员等级,对应的打折价格都是不一样的,很复杂。

    所以这里对于上端执行算法呢,我们要引入一个上下文(Context)。大家也可以延伸想一想,HttpContext:就是用来保存http的一些状态信息,Cookie,Session等等。我们这个上下文对象就是用来保存这次算法执行的一些初始化信息,中间变量,结果值等等(因为我们刚刚已经说,这个算法的执行是非常复杂的,需要做很多的准备)。

        public class DiscountContext
        {
            private readonly double _oldPrice;private readonly IStrategy _strategy;
            
    
            public DiscountContext(double oldPrice,IStrategy strategy){this._oldPrice = oldPrice;
                this._strategy = strategy;
            }
    
            public double Excute(){
                //很复杂的操作,不同操作系统,对应不同策略等等。
                Console.WriteLine("写日志");
                Console.WriteLine("做缓存");
                return this._strategy.GetDiscountPrice(this._oldPrice);
    
            }

          引入了这个类之后呢,我们上端也要进行修改一下;

      Console.WriteLine("请输入商品折扣");
                    int discount = Convert.ToInt32(Console.ReadLine());
                    IStrategy gy = null;
                    //假设有9折,8折,7折
                    switch (discount) {
                        case 7:
                            //打七折的时候,要多加十块
                            //discountPrice = goodsPrice * 0.7 + 10;
                            gy=new Seven();
                            break;
                        case 8:
                            //打八折的时候,要多加十块
                            //discountPrice = goodsPrice * 0.8 + 8;
                            gy = new Eight();
                            break;
                        case 9:
                            //打七折的时候,要多加十块
                            //discountPrice = goodsPrice * 0.9 + 5;
                            gy = new Night();
                            break;
                    }
                    var disContext=new DiscountContext(100,gy);
                    Console.WriteLine($"打折后总价为:{disContext.Excute()}");

        到此,我们的策略模式就结束了。下面来对上面进行一个总结:所谓的策略模式,首先要有很多策略(算法)先,才需要对所有策略,进行一个公共的抽取,让所有策略都继承自抽象;然后因为每个策略执行的复杂性以及诸多因素,我们需要把策略的执行过程,封装为一个上下文。策略模式的三要素:1、策略(有很多策略),2、策略的接口,3、上下文;

       

       (三)策略模式的优缺点

         优缺点,大家从上面应该是显而易见的了,优点:算法之间,可以自由转换。

         缺点:没一个算法类的复用性不高,增加了很多类。

      (四)策略模式和工厂模式结合

           

          由于时间关系,大家可以想想该怎么做。

  • 相关阅读:
    io学习
    asp.net文件上传进度条研究
    asp.net页面中的Console.WriteLine结果如何查看
    谨慎跟随初始目的不被关联问题带偏
    android 按钮特效 波纹 Android button effects ripple
    安卓工作室 日志设置
    安卓工作室 文件浏览器 android studio File browser
    一个新的Android Studio 2.3.3可以在稳定的频道中使用。A new Android Studio 2.3.3 is available in the stable channel.
    新巴巴运动网上商城 项目 快速搭建 教程 The new babar sports online mall project quickly builds a tutorial
    码云,git使用 教程-便签
  • 原文地址:https://www.cnblogs.com/gdouzz/p/8377076.html
Copyright © 2011-2022 走看看