2013年10月8日 星期二

Design Pattern : Abstract Factory

Design Pattern : Abstract Factory 抽象工廠模式

Definition :
  Provide an interface for creating families of related or dependent objects without specifying their concrete classes.


Design Pattern : Factory工廠模式 (泛型) 有提到如何使用Abstractoverride方法來建立Factory
這邊則會以Interface的方式來實作抽象工廠。




1.  先建立Interface : ICarFactory
interface ICarFactory
{
  F Create<F, T>()
where T : F, new();
}



2.  開始建立FORDCarFactory
public F Create<F, T>() where T : F, new()
{

 
String typeName = typeof(T).Name; //取得要建立的類別名稱
 
if (typeName == typeof(DPLib.Focus).Name)
  {
   
return new T();
  }
 
else
  {
   
throw new Exception(
      
String.Format("FORD : Cannot create {0}!", typeName));
  }
}


u  上面程式碼主要是判斷是否為FORD的車子,如果是他牌,則丟出無法Create的例外。
u  Abstract Factory可以很輕易的建立其他品牌的Factory,例如HONDA, VOLVO …
只要再新增對應實作ICarFactory Factory即可。

3.  主程式:
ICarFactory factory = new FordFactory();
try {
  
///Create FORD Focus
  
DPLib.ICar _focus = factory.Create<DPLib.ICar, DPLib.Focus>();
   _focus.Color = DPLib.
Color.Yellow;
   _focus.Drive();

  
///Try Create VOLVO V60
  
DPLib.ICar _v60 = factory.Create<DPLib.ICar, DPLib.V60>();
   _v60.Color = DPLib.
Color.Yellow;
   _v60.Drive();
}
catch(Exception ex){
  
Console.WriteLine(ex.Message);
}


執行結果:
I am driving Yellow Focus (FORD)
FORD : Cannot create V60!

4.  如果要在Factory裡面去詳細定義車子的內容(例如顏色名稱 ),則可以修改為以下的程式碼。

ICarFactory :
interface ICarFactory
{
  DPLib.
ICar CreateSpe<T>(String carName, DPLib.Color color) where T : DPLib.ICar, new();
  F CreateSpe<F,T>(
String carName, DPLib.Color color) where T :F, new();
}


FordFactory :

public DPLib.ICar CreateSpe<T>(String carName, DPLib.Color color) where T : DPLib.ICar, new()
public F CreateSpe<F,T>(String carName, DPLib.Color color) where T : F, new()
{
  
String typeName = typeof(T).Name; //取得要建立的類別名稱
  
if (typeName == typeof(DPLib.Focus).Name)
   {
      DPLib.
ICar _newCar = new DPLib.Focus();
     
dynamic _newCar = new T();
     
_newCar.Name = carName;
     
_newCar.Color = color;
     
return _newCar;
   }
  
else
   {
     
throw new Exception(
       
String.Format("FORD : Cannot create {0}!", typeName));
   }
}

u  刪除的部分惟後來改用dynamic寫法 J



5.  從以上可以發現Abstract Factory的優點:
可以很輕易的擴增新的有共同行為的Factory
 但是缺點:
如果需要要新增一種服務,必須在ICarFactory裡面新增,也意味著必須去修改實作它的所有Factory。」
例如我們要新增一個製造摩托車的服務,則ICarFactory會變成:

interface ICarFactory
{
  F CreateCar<F, T>()
where T : F, new();
 
F CreateScooter<F, T>() where T : F, new();
}


往下實作的Factory Class可都要去新增一個方法了。


6.  Reference
Generic Abstract Factory


沒有留言:

張貼留言