簡單工廠模式和策略模式的區別與結合


前言:

    簡單工廠模式和策略模式是大部分程序員,在學習設計模式時接觸得最早,或在工作實踐中也是用得相對比較多的兩個設計模式。

    一個是創建型,另一個是行為型,然而兩種不同類型的模式,在某些地方也有一絲的相似之處,同時在某種場景下結合使用,能起到特別好的效果。

問題:

   我覺得簡單工廠模式和策略模式很相似。怎么相似?都是三個業務子類繼承抽象父類,通過傳入參數到容器類(工廠模式的factory類,策略模式的Content類),選擇對應的類進行行為操作。

   其實,UML圖的確從外形上看沒多大區別,但是,本質卻是大大不同。

簡單工廠模式

   上面提到過,簡單工廠模式是創建型模式,創建型模式顧名思義,也就是說在創建對象的時候,遇到了瓶頸才會選擇的設計模式。那么該什么情況使用呢。

   簡單工廠模式的實質是由一個工廠類根據傳入的參數,動態決定應該創建並且返回哪一個產品類(這些產品類繼承自一個父類或接口)的實例。

   那么也就是說:

   1、有已知的產品類

   2、你無法准確的知道編譯哪個產品類

   3、需要在運行時決定創建哪個產品類

   4、產品類不多

   很明顯看出,在創建對象上的靈活性高,但是工廠類只能創建可能會使用到的產品類,假如新添了產品類就得修改工廠類,這樣就會違反開閉原則。

策略模式

  策略模式是行為型模式,它定義了一系列的算法,並將每一個算法封裝起來,而且使它們還可以相互替換。策略模式讓算法獨立於使用它的客戶而獨立變化。

  在一段代碼里,使用了邏輯控制(if-else,swich-case)來決定算法,算法有相似的方法和函數,就可以選擇策略模式。

  那么也就是說:

  1、某方法里有多個條件語句,條件語句代碼塊里有許多行為過程。

  2、其算法能封裝到策略類

  2、算法隨意切換

  3、算法與客戶端隔離

   這樣一來,通過選擇對應的策略類,作為參數傳到Content類里,在運行時配置對應的算法。

區別總結

  從上面的描述總結出,在運行時,兩者都是通過傳入參數進行配置,簡單工廠模式則是選擇創建出需要的對象,而策略模式則是配置出需要的行為算法。一個是對象創建,另一個是行為算法的替換。

 

結合

  下面有一段策略模式的代碼。

using System;
using System.Net.Configuration;

namespace StrategyWithFactory
{
    class Program
    {
        static void Main(string[] args)
        {
            Strategy strategyContent = null;

            //偽代碼。獲取輸入算法類型
            EStrategy inputType = RequestInput();

            if (inputType == EStrategy.A)
            {
                new Content(new StrategyA()).ContentInterface();
            }
            else if (inputType == EStrategy.B)
            {
                new Content(new StrategyB()).ContentInterface();
            }
            else if (inputType == EStrategy.C)
            {
                new Content(new StrategyC()).ContentInterface();
            }
        }
    }

    //算法抽象類
    abstract class Strategy
    {
        public abstract void AlfoeirhmInterface();
    }

    //A算法類
    class StrategyA : Strategy
    {
        public override void AlfoeirhmInterface()
        {
            Console.WriteLine("this is the StrategyA");
        }
    }

    //B算法類
    class StrategyB : Strategy
    {
        public override void AlfoeirhmInterface()
        {
            Console.WriteLine("this is the StrategyB");
        }
    }

    //B算法類
    class StrategyC : Strategy
    {
        public override void AlfoeirhmInterface()
        {
            Console.WriteLine("this is the StrategyC");
        }
    }

    //上下文類
    class Content
    {
        private readonly Strategy _strategy;
        public Content(Strategy strategy)
        {
            _strategy = strategy;
        }

        public void ContentInterface()
        {
            _strategy.AlfoeirhmInterface();
        }
    }

    //算法枚舉
    enum EStrategy
    {
        A = 1,
        B = 2,
        C = 3
    }
}

 

   上面的代碼是策略模式的原型,假如Main函數是客戶端,那么以后每加一個算法,都得在客戶端修改一次,添加一個else if,引起了不必要的麻煩。那么,現在的情況,首先我們知道已有的ABC三種算法,但是我們又不確定運行時使用哪種算法,同時為了讓客戶端和業務邏輯代碼隔離開,於是,我們可以將客戶端的創建算法類的業務邏輯轉移到Cotent類,並添加一個創建算法工廠的方法。

using System;

namespace StrategyWithFactory
{
    class Program
    {
        static void Main(string[] args)
        {
            //偽代碼。獲取輸入算法類型
            EStrategy inputType = RequestInput();
            new Content(inputType).ContentInterface();
        }
    }

    //上下文類
    class Content
    {
        private readonly Strategy _strategy;
        public Content(EStrategy eStrategy)
        {
            _strategy = CreateFactory(eStrategy);
        }

        public Strategy CreateFactory(EStrategy eStrategy)
        {
            Strategy strategy = null;
            switch (eStrategy)
            {
                case EStrategy.A:
                    strategy = new StrategyA();
                    break;

                case EStrategy.B:
                    strategy = new StrategyB();
                    break;

                case EStrategy.C:
                    strategy = new StrategyC();
                    break;
            }
            return strategy;
        }

        public void ContentInterface()
        {
            _strategy.AlfoeirhmInterface();
        }
    }
}

  那么,策略和簡單工廠的結合應用就實現了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM