西西軟件園多重安全檢測下載網(wǎng)站、值得信賴的軟件下載站!
軟件
軟件
文章
搜索

首頁編程開發(fā)C#.NET → C#抽象工廠模式實現(xiàn)方法

C#抽象工廠模式實現(xiàn)方法

相關(guān)軟件相關(guān)文章發(fā)表評論 來源:本站整理時間:2010/11/15 15:19:20字體大。A-A+

作者:佚名點擊:33次評論:0次標(biāo)簽: C#

API精靈FOR c#v2.35 最新版
  • 類型:編程輔助大。324KB語言:中文 評分:7.5
  • 標(biāo)簽:
立即下載
 利用設(shè)計模式可以使我們的代碼更靈活,更容易擴展,更容易維護。各種面向?qū)ο蟮某绦蛟O(shè)計語言都提供了基本相同的機制:比如類、繼承、派生、多態(tài)等等。但是又有各自的特色,C# 中的反射機制便是一個很重要的工具,好好地利用就可以在實際中發(fā)揮很大的作用。

   我們來看一個例子:

   我的程序中有需要一系列的對象,比如apple,orange…, 要想利用他們,我們就必須在程序中根據(jù)用戶要求,然后一個個調(diào)用 new 操作符來生成他們,這樣客戶程序就要知道相應(yīng)的類的信息,生成的代碼顯然不夠靈活。我們可以在代碼中不利用具體的類,而只是說明我們需要什么,然后就能夠得到我們想要的對象嗎?

   哦,我們都看設(shè)計模式,聽吧,很多人都在那里鼓吹他們是如何如何的棒,我們看看怎么樣利用他們來解決問題。目標(biāo)明確了,那我們看看哪個能夠符合我們的要求。GoF的《設(shè)計模式》都看過吧,似懂非懂的看了一些,那我們看看能夠不能夠“湊”上去呢?J 嗯,我們的程序考慮的是對象怎么創(chuàng)建的,創(chuàng)建型模式應(yīng)該符合要求吧。然后我們?yōu)g覽一下各模式的“意圖”部分。呵呵,第一個好像就撞到彩了,抽象工廠,我們看看吧,“提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口,而無需指定它們具體的類”,至少“無需指定它們具體的類”符合我們的要求。來看看它的結(jié)構(gòu)吧:



   我們的問題好像用不到這么復(fù)雜吧,只有orange,apple等等(應(yīng)該就是product了),他們顯然是一類的,都是fruit,我們只要一個生產(chǎn)水果的工廠就可以,左邊的繼承層次不要,只有一個FruitFactroy看看行不,先別管它正統(tǒng)不正統(tǒng),實用就行J

   下面的一些東西顯然是我們需要的:

Public interface IFruit
{
}

public class Orange:IFruit
{
  public Orange()
  {
   Console.WriteLine("An orange is got!");
  }
}

public class Apple:IFruit
{
  public Apple()
  {
   Console.WriteLine("An apple is got!");
  }
}

   我們的FruitFactory應(yīng)該是怎么樣呢?上面的結(jié)構(gòu)圖中它給的是CreateProductA,那好,我就MakeOrange,還有一個CreateProductB,俺MakeOrange還不行??

public class FruitFactory
{
  public Orange MakeOrange()
  {
   return new Orange();
  }
  public Apple MakeApple()
  {
   return new Apple();
  }
}

   怎么使用這個工廠呢?我們來寫下面的代碼:

string FruitName = Console.ReadLine();
IFruit MyFruit = null;
FruitFactory MyFruitFactory = new FruitFactory();

switch (FruitName)
{
  case "Orange":
   MyFruit = MyFruitFactory.MakeOrange();
   break;
  case "Apple":
   MyFruit = MyFruitFactory.MakeApple();
   break;
  default:
   break;
}

   編譯運行,然后在控制臺輸入想要的東西,呵呵,成功了。沉浸在幸福中的你得意忘形了吧。
   不過等等,它好像還不完美,我如果想要pear,我既要在客戶代碼中的switch中加入判斷,又要在工廠方法中加入MakePear方法,好像不怎么優(yōu)雅。更好一點,在工廠中只提供一個方法,MakeFruit,然后傳遞進一個參數(shù)Name,代表我們想要的水果的名稱,這樣的話,似乎我們的客戶代碼中的那個switch就可以不要了,相反,在FruitFactory中好像需要一個,還等什么呢?實現(xiàn)吧。

FruitFactory:
public class FruitFactory
{
  public IFruit MakeFruit(string Name)
  {
   switch (Name)
   {
    case "Orange":
     return new Orange();
    case "Apple":
     return new Apple();
    default:
     return null;
   }
  }
}

   客戶代碼:

string FruitName = Console.ReadLine();
IFruit MyFruit;
FruitFactory MyFruitFactory = new FruitFactory();
MyFruit = MyFruitFactory.MakeFruit(FruitName);

   這樣看起來好多了,至少我客戶代碼中不要再寫那么一長串的判斷代碼了。

   阿Q精神又在起作用,我們又沉浸在成功的喜悅中了。 嗯,代碼好像可以,應(yīng)該沒有什么改進了。但是好像又有另外一個聲音在說:

   “除了一點……”

   “嗯? 等等,什么?”

   “FruitFactory也有switch啊,看起來也ugly!”

   “哼,肯定是看《重構(gòu)》或者是《TDD》了,怎么要求那么苛刻!反正閑著也是閑著,看看可以改不?”

   既然不要條件判斷,傳入的只有水果的名稱,假如Name = “Apple”,要生成一個Apple的對象,我需要new Apple(),如果我能夠這樣多好: new MakeItToClass(Name),把字符串轉(zhuǎn)換成一個類。C#中雖然沒有上述語法,但是提供了相應(yīng)的機制,那就是反射。其中一個重要的類就是System.Type類,它對于反射起著核心的作用。我們可以使用 Type 對象的方法、字段、屬性和嵌套類來查找有關(guān)該類型的所有信息。

   另外一個重要的類就是System.Activator,它包含特定的方法,用以在本地或從遠(yuǎn)程創(chuàng)建對象類型,或獲取對現(xiàn)有遠(yuǎn)程對象的引用。

   我們可以先利用Type類獲取Name指定的類名的類的Type信息,然后可以根據(jù)這個信息利用Activator創(chuàng)建對象。還等什么呢?

public class FruitFactory
{
  public IFruit MakeFruit(string Name)
  {
   IFruit MyFruit = null;
   try
   {
    Type type = Type.GetType(Name,true);
    MyFruit = (IFruit)Activator.CreateInstance(type);
   }
   catch (TypeLoadException e)
    Console.WriteLine("I dont know this kind of fruit,exception caught - {0}" ,e.Message);
    return MyFruit;
  }
}

   經(jīng)過這樣的處理以后,增加新的水果的時候,我們不需要修改客戶代碼了,同時工廠的代碼也不需要修改了,怎么樣,爽吧!

 

    相關(guān)評論

    閱讀本文后您有什么感想? 已有人給出評價!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過難過
    • 5 囧
    • 3 圍觀圍觀
    • 2 無聊無聊

    熱門評論

    最新評論

    發(fā)表評論 查看所有評論(0)

    昵稱:
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字?jǐn)?shù): 0/500 (您的評論需要經(jīng)過審核才能顯示)