[C#]抽象原廠模式的幾種實現方法及比較

來源:互聯網
上載者:User

利用設計模式可以使我們的代碼更靈活,更容易擴充,更容易維護。各種物件導向的程式設計語言都提供了基本相同的機制:比如類、繼承、派生、多態等等。但是又有各自的特色,C# 中的反射機制便是一個很重要的工具,好好地利用就可以在實際中發揮很大的作用。

我們來看一個例子:

我的程式中有需要一系列的對象,比如apple,orange…, 要想利用他們,我們就必須在程式中根據使用者要求,然後一個個調用 new 操作符來產生他們,這樣客戶程式就要知道相應的類的資訊,產生的程式碼顯然不夠靈活。我們可以在代碼中不利用具體的類,而只是說明我們需要什麼,然後就能夠得到我們想要的對象嗎?

我們的程式考慮的是對象怎麼建立的,建立型模式應該符合要求吧。然後我們瀏覽一下各模式的“意圖”部分。第一個好像就撞到彩了,抽象工廠,我們看看吧,“提供一個建立一系列相關或相互依賴對象的介面,而無需指定它們具體的類”,至少“無需指定它們具體的類”符合我們的要求。來看看它的結構吧!

我們的問題好像用不到這麼複雜吧!只有orange,apple等等(應該就是product了),他們顯然是一類的,都是fruit,我們只要一個生產水果的工廠就可以,左邊的繼承層次不要,只有一個FruitFactroy看看行不,先別管它正統不正統,實用就行。

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

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應該是怎麼樣呢?上面的結構圖中它給的是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中加入判斷,又要在Factory 方法中加入MakePear方法,好像不怎麼優雅。更好一點,在工廠中只提供一個方法,MakeFruit,然後傳遞進一個參數Name,代表我們想要的水果的名稱,這樣的話,似乎我們的客戶代碼中的那個switch就可以不要了,相反,在FruitFactory中好像需要一個,還等什麼呢?實現吧!

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);

這樣看起來好多了,至少我客戶代碼中不要再寫那麼一長串的判斷代碼了。
既然不要條件判斷,傳入的只有水果的名稱,假如Name = “Apple”,要產生一個Apple的對象,我需要new Apple(),如果我能夠這樣多好: new MakeItToClass(Name),把字串轉換成一個類。C#中雖然沒有上述文法,但是提供了相應的機制,那就是反射。其中一個重要的類就是System.Type類,它對於反射起著核心的作用。我們可以使用 Type 對象的方法、欄位、屬性和嵌套類來尋找有關該類型的所有資訊。
另外一個重要的類就是System.Activator,它包含特定的方法,用以在本地或從遠程建立物件類型,或擷取對現有遠程對象的引用。 
我們可以先利用Type類擷取Name指定的類名的類的Type資訊,然後可以根據這個資訊利用Activator建立對象。

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;
  }
}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.