C#實現策略模式

場景:有一個喜歡吃餃子,他有三種不同的方式去吃,蒸餃子,煮餃子,煎餃子,想要用策略模式來設計這個場景,怎麼弄?

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

class Boiled : EatMethod
{
   public override void Eat()
   {
     Console.WriteLine("This is boiled 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而已,但是還是有些不同的,詳見//www.jb51.net/article/254877.htm

這裡和上面的簡單工廠隻有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圖發現,兩者好像沒有什麼差別,可能理解還不深入吧,寫得可能有些地方還不是很正確,希望看到的高手能指點一二。

到此這篇關於C#實現策略模式的文章就介紹到這瞭。希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: