[Design Pattern] 簡單工廠模式 Simple Factory Pattern

簡單工廠模式 => 幫我選擇出用戶實際要用的是哪個子類別

 

99.99 的人學 DP 的第一課都是簡單工廠

因為它簡單又好用

今天學會 明天馬上用得到

 

而它的精華就是在這個 Factory

public static Housework CreateHousework(string oper)
{
    Housework obj = null;

    switch (oper)
    {
        case "洗碗":
            obj = new WashDish();
            break;
        case "掃地":
            obj = new CleanFloor();
            break;
        case "倒垃圾":
            obj = new TakeOutGarbage();
            break;
    }

    return obj;
}

很明顯的哪些情況成立時 這個 DP 才用的上

1. 有一個父類別,有許多子類別繼承它,而我要根據參數決定現在要用哪一個子類別

2. 父類別裡有個函式 ex: Do(),所有子類別都各自實作成自己的樣子,才能達到統一函式名稱的呼叫

 

也就是說 主程式的程式碼會像這樣

static void Main(string[] args)
{
    var housework = HomeworkFactory.CreateHousework("掃地");

    //因為所有子類別都 Override 同一個父類別的事件,所以呼叫的程式碼一定一樣
    housework.Do();
}

 

而學習 DP 有一個很重要的地方 就是命名

很多程式給你寫 你可能可以寫的比大師們的 DP 更屌

但大家不認識你 我不從第一行看到最後一行 我不會知道你在寫什麼

 

而 DP 就是這樣的存在 有時後也不見得說它是多必要

只是當看到幾個關鍵字 大家不用看完你所有程式碼 就大概猜的出來你想做什麼

因為這是大家共通的語言

所以學習 DP 有一件很重要的事 就是試著讓命名符合大家的慣例

 

比如以簡單工廠來說

1. 一定有一個工廠類別叫 xxxFactory

2. 裡面一定有個函式叫 CreateXXX

3. 這個函式一定吐一個子類別給我

4. 子類別一定 override 一個父類別的函式

 

因為大家都這樣做 所以我不用看完你的程式碼

我大概看到幾個關鍵字 我就會猜想你的程式大概是這樣運作

這就是 DP 主要的功用

把一個常見的程式架構 建立出一種大家共通的語言 來縮短大家看程式碼的時間

 

假設今天的題目是這樣

1. 我有洗碗、掃地、倒垃圾 => 都繼承至 '家事'

2. 共通的函式名稱叫 Do()

3. 叫用時,輸入今天要做的家事名稱,再呼叫 Do() 即可完成

 

接下來我們就可以看完整的程式碼

[類別] 1.主程式  2.Factory  3.要被工廠拿來 switch case 的子類別們 (與他們的父類別)

[流程] 主程式 => 透過Factory => 決定現在要用哪個子類別


namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var housework = HomeworkFactory.CreateHousework("掃地");

            //因為所有子類別都 Override 同一個父類別的事件,所以呼叫的程式碼一定一樣
            housework.Do();
        }
    }

    //---------------------------------------------------
    /// <summary>
    /// 命名 => xxxFactory
    /// </summary>
    class HomeworkFactory
    {
        //命名 => CreateXXX
        //回傳 => 子類別
        public static Housework CreateHousework(string oper)
        {
            Housework obj = null;

            switch (oper)
            {
                case "洗碗":
                    obj = new WashDish();
                    break;
                case "掃地":
                    obj = new CleanFloor();
                    break;
                case "倒垃圾":
                    obj = new TakeOutGarbage();
                    break;
            }

            return obj;
        }
    }

    //---------------------------------------------------
    abstract class Housework
    {
        /// <summary>
        /// 父類別一定有些被所有子類別共同 override 的函式
        /// </summary>
        public abstract void Do();
    }

    class WashDish : Housework
    {
        public override void Do()
        {
            //用洗碗精、沖乾淨
        }
    }

    class CleanFloor : Housework
    {
        public override void Do()
        {
            //掃把掃地、畚斗集中灰塵倒垃圾桶
        }
    }

    class TakeOutGarbage : Housework
    {
        public override void Do()
        {
            //打包垃圾、出門等垃圾車
        }
    }
}