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

    场景:有一个喜欢吃饺子,他有三种不同的方式去吃,蒸饺子,煮饺子,煎饺子,想要用策略模式来设计这个场景,怎么弄?

    1.复习简单工厂模式

    具体的代码:

    EatMethod.cs

    public class EatMethod
    {
    public virtual void Eat() { Console.WriteLine("This is the base class!"); } }

    Steamed.cs

    class Steamed : EatMethod
    {
       public override void Eat()
       {
           Console.WriteLine("This is steamed dumplings!");
       }
    }

    Boiled.cs

    class Boiled : EatMethod
    {
    public override void Eat() { Console.WriteLine("This is boiled dumplings!"); } }

    Fried.cs

    public class Fried:EatMethod
    {
          public override void Eat()
          {
               Console.WriteLine("This is fired dumplings!");
          }
    }

    EatFactory.cs

    public static class EatFactory
    {
       public static EatMethod CreateEatMethod(string eatMethod)
       {
           EatMethod eat = null;
           switch (eatMethod)
           {
              case "Steamed":
                   eat = new Steamed();
                   break;
              case "Boiled":
                   eat = new Boiled();
                   break;
              case "Fried":
                   eat = new Fried();
                   break;
              default:
                   break;
                }
            return eat;
        }
    }

    Program.cs

    class Program
    {
        static void Main(string[] args)
        {
            EatMethod eat = EatFactory.CreateEatMethod("Steamed");
            eat.Eat();
            eat = EatFactory.CreateEatMethod("Boiled");
            eat.Eat();
            eat = EatFactory.CreateEatMethod("Fried");
            eat.Eat();
        }
    }

    测试结果:

    2.策略模式来设计

    上面虽然用简单工厂实现了,但是感觉各种吃饺子的方式,用工厂来创建还是显得比较生硬,每一种吃法应该看成是一种算法,最终的目的都是吃掉,所以这里就引出了策略模式的概念了。

    策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。

    这个模式涉及到三个角色:

    • 环境(Context)角色:持有一个Strategy类的引用。
    • 抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
    • 具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。

    看了UML图感觉和简单工厂也没啥区别啊,不过是把Factory变成了Context而已,但是还是有些不同的,详见http://www.cnblogs.com/me115/p/3790615.html

    这里和上面的简单工厂只有EatContext和客户端不一样

    EatContext.cs

     public class EatContext  
     {
          private EatMethod _eat;
    
          public EatContext(EatMethod eat)
          {
              _eat = eat;
          }
    
          public void Eat()
          {
             _eat.Eat();
          }
     }

    Program.cs

    EatContext ec = new EatContext(new Steamed());
    ec.Eat();
    ec = new EatContext(new Boiled());
    ec.Eat();
    ec = new EatContext(new Fried());
    ec.Eat();

    测试执行结果:

    3.对比策略模式和简单工厂模式

    我的理解是这样的:

    首先是简单工厂模式:

    客户端去调用工厂中的CreateEatMenthod方法,从输入上看,是一个字符串,指明了我想要的对象,然后工厂方法,就返回了一个我想要的对象,后面的具体的Eat(),是在客户端使用返回的对象进行调用的。

    然后是策略模式:

    客户端实例化一个EatContext对象,传入的参数是一个具体的怎么做饺子的对象,然后EatContext根据传入的对象,来初始化一个EatContext对象,后续的客户端操作通过的是EatContext的实例对象来完成的。

    上面也能看出来,简单工厂用于创建对象,而策略模式更在乎控制行为,所以前者是创建型模式,后者是行为型模式。

    实际应用中,可以将两者在进一步结合,再修改一下程序

    EatFactoryContext.cs

    public class EatFactoryContext
    {
        EatMethod _eat = null;
        public EatFactoryContext(string eatMethod)
        {
            switch (eatMethod)
            {
                case "Steamed":
                    _eat = new Steamed();
                    break;
                case "Boiled":
                    _eat = new Boiled();
                    break;
                case "Fried":
                    _eat = new Fried();
                    break;
                default:
                    break;
                }
            }
    
       public void Eat()
       {
          _eat.Eat();
       }
    }

    Program.cs

    #region 结合
    EatFactoryContext efc = new EatFactoryContext("Steamed");
    efc.Eat();
    efc = new EatFactoryContext("Boiled");
    efc.Eat();
    efc = new EatFactoryContext("Fried");
    efc.Eat();
    #endregion

    测试结果:

    4.总结

    经过学习呢,发现是能够把简单工厂和策略模式进行基本的了解,但是如果工作中没有实际遇到,的确对于两者的区别的理解感到困惑,可能很多人和我一样,都是看到UML图发现,两者好像没有什么差别,可能理解还不深入吧,写得可能有些地方还不是很正确,希望看到的高手能指点一二。

  • 相关阅读:
    输入一行文字,找出其中大写字母、小写字母、空格、数字以及其他字符各有多少
    有一字符串,包含n个字符。写一函数,将此字符串中从第m个字符开始的全部字符复制成为另一个字符串
    写一函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度
    有n个人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位
    有n个整数,使前面各数顺序向后移m个位置,最后m个数变成最前面m个数,见图8.43 写一函数实现以上功能,在主函数中输人n个整数和输出调整后的n个数
    输入10个整数,将其中最小的数与第一个数对换, 把最大的数与最后一个数对换
    LOJ#3271. 「JOISC 2020 Day1」建筑装饰 4 DP+找规律
    LOJ#3160. 「NOI2019」斗主地 打表+拉格朗日插值
    CF1386C Joker 双指针+动态树
    LuoguP2605 [ZJOI2010]基站选址 线段树优化DP
  • 原文地址:https://www.cnblogs.com/dcz2015/p/5264953.html
Copyright © 2011-2022 走看看