文章出處

上一篇, 介紹了簡單工廠模式, 在最后提出了一個問題, 如果我的程序需要擴展, 加一種產品進去, 顯然, 簡單工廠是不能勝任此項工作的, 那么需要另請高明 - 工廠方法模式. 當然, 抽象工廠, 也是可以加產品的, 動態添加程序集, 然后反射的方式就可以創建出我們新加的對象. 不過此處, 主要還是介紹工廠方法模式.

一、工廠方法模式

Normal, SUV, Sports 這幾個類, 仍然沿用之前的, 不動. 此處, 主要是從工廠處開刀. 

設計思想: 既然工廠返回值是變化的, 熱插拔的, 那么我們能做的, 就是分析他們, 提取出他們的抽象部分. 之前的工廠是固定的, 現在我們為他們新建各自的工廠, 由各自的工廠負責創建他們的類, 然后把各自的工廠抽象出來, 形成一個工廠接口, 抽象類也是可以的. 這里就是哪里變化封裝哪里的思想了.

代碼如下:

public interface ICarFactory
{
    Car Create();
}

public class NormalFactory : ICarFactory
{
    public Car Create()
    {
        return new Normal();
    }
}

public class SUVFactory : ICarFactory
{
    public Car Create()
    {
        return new SUV();
    }
}

public class SportsFactory : ICarFactory
{
    public Car Create()
    {
        return new Sports();
    }
}

測試代碼如下:

static void Main(string[] args)
{
    ICarFactory factory =  new NormalFactory();
    Car car = factory.Create();
    car.Start();

    Console.ReadKey();
}

結果如下:

類圖:

到這里, 工廠方法已經浮出水面了, 接下來, 用這種方式, 去實現熱插拔, 你會發現, 我丟, 在逗我嗎? 這怎么可能實現功能. 好吧, 我承認, 程序寫到這里, 還不能滿足需求, 接下來, 還需要一個小的改動, 其實方法很簡單. 修改如下:

//<add key="CarFactory" value="Mod.SportsFactory"/>
string factoryName = ConfigurationManager.AppSettings["CarFactory"];
ICarFactory factory = (ICarFactory)Assembly.Load("Mod").CreateInstance(factoryName);
Car car = factory.Create();
car.Start();

我們可以動態添加程序集, 只需要修改下配置文件中, 要創建的那個類名即可. 不需要去修改原來的代碼, 還有一件同樣重要的事情就是, 測試不會再叫了, 不需要測試以前的部分, 否則, 只要動代碼, 就是給測試找活干, 會被打的. 哈哈

這個例子, 本身就是一個比較好的用例場景了, 所以就不在給出別的用例場景了. 還是滿符合設計原則的.

在我們強大的反射面前, 其實不需要什么簡單工廠啊, 工廠方法啊, 就可以直接實現, 創建出需要的類, 當然也可以, 動態添加程序集, 實現熱插拔

//<add key="CarName" value="Mod.Normal"/>
string carName = ConfigurationManager.AppSettings["CarName"];
Car car1 = (Car)Assembly.Load("Mod").CreateInstance(carName);
car1.Start();

Console.ReadKey();

只不過, 這種實現方式, 就不是工廠模式的思想了, 具體使用哪種實現方式, 根據情況而定, 不要過, 也不要少.  嘿嘿, 換句話說, 就是不要給自己找事做, 合適即可.

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()