文章出處

索引

別名

  • 虛構造器 (Virtual Constructor)

意圖

定義一個用于創建目標對象的接口,讓子類決定實例化哪一個目標類。

Factory Method 使一個類的實例化延遲到其子類。

Define an interface for creating an object, but let subclasses decide which class to instantiate.

Factory Method lets a class defer instantiation to subclasses.

結構

參與者

Product

  • 定義工廠方法所創建的對象的接口(Interface)。

ConcreteProduct

  • 實現 Product 接口。

Creator

  • 聲明工廠方法,該方法返回一個 Product 類型的對象。 Creator 也可以定義一個工廠方法的缺省實現,它返回一個缺省的 ConcreteProduct 對象。
  • 可以調用工廠方法以創建一個 Product 對象。

ConcreteCreator

  • 重定義(Override)工廠方法以創建一個 Product 對象。

適用性

在下列情況下可以使用 Factory Method 模式:

  • 當一個類不知道它所必須創建的對象的類的時候。
  • 當一個類希望由它的子類來指定它所創建的對象的時候。
  • 當類將創建對象的職責委托給多個幫助子類中的某一個,并且你希望將哪一個幫助子類是代理者這一信息局部化的時候。

缺點

  • 客戶可能僅僅為了創建一個特定的 ConcreteProduct 對象,就不得不創建 Creator 的子類。

效果

  • 為子類提供掛鉤
  • 連接平行的類層次

相關模式

  • Abstract Factory 經常用工廠方法來實現。
  • Factory Method 通常在 Template Method 中被調用。
  • Prototype 不需要創建 Creator 的子類。但是,它們通常要求一個針對 Product 類的 Initialize 操作。Creator 使用 Initialize 來初始化對象,而 Factory Method 不需要這樣的操作。

命名約定

使用命名約定是一個好習慣,它可以清楚地說明你正在使用工廠方法。(Convention over Configuration)

例如,總是聲明那些定義為工廠方法的抽象操作為 CreateProduct()。

實現

實現方式(一):Creator 類是一個抽象類并且不提供它所聲明的工廠方法的實現。

需要子類來定義實現,因為沒有合理的缺省實現。它避免了不得不實例化不可預見類的問題。

 1 namespace FactoryMethodPattern.Implementation1
 2 {
 3   public abstract class AbstractOrInterfaceOfCreator
 4   {
 5     public abstract AbstractOrInterfaceOfProduct CreateProduct();
 6   }
 7 
 8   public abstract class AbstractOrInterfaceOfProduct
 9   {
10   }
11 
12   public class ConcreteCreator : AbstractOrInterfaceOfCreator
13   {
14     public override AbstractOrInterfaceOfProduct CreateProduct()
15     {
16       return new ConcreteProduct();
17     }
18   }
19 
20   public class ConcreteProduct : AbstractOrInterfaceOfProduct
21   {
22   }
23 
24   public partial class Test
25   {
26     public void Case1()
27     {
28       AbstractOrInterfaceOfCreator creator = new ConcreteCreator();
29       AbstractOrInterfaceOfProduct product = creator.CreateProduct();
30     }
31   }
32 }

實現方式(二):Creator 類是一個具體類而且為工廠方法提供一個缺省的實現。

具體的 Creator 主要因為靈活性才使用工廠方法。它所遵循的準則是,“用一個獨立的操作創建對象,這樣子類才能重定義它們的創建方法”。這條準則保證了子類的設計者能夠在必要的時候改變父類所實例化的對象的類。

 1 namespace FactoryMethodPattern.Implementation2
 2 {
 3   public class ConcreteCreator
 4   {
 5     public virtual AbstractOrInterfaceOfProduct CreateProduct()
 6     {
 7       return new ConcreteProduct();
 8     }
 9   }
10 
11   public abstract class AbstractOrInterfaceOfProduct
12   {
13   }
14 
15   public class ConcreteProduct : AbstractOrInterfaceOfProduct
16   {
17   }
18 
19   public partial class Test
20   {
21     public void Case2()
22     {
23       ConcreteCreator creator = new ConcreteCreator();
24       AbstractOrInterfaceOfProduct product = creator.CreateProduct();
25     }
26   }
27 }

實現方式(三):參數化工廠方法。

使用參數化工廠方法可以創建多種產品。工廠方法采用一個標識要被創建的對象種類的參數。

 1 namespace FactoryMethodPattern.Implementation3
 2 {
 3   public enum ProductCategory
 4   {
 5     GoodProduct,
 6     BadProduct,
 7   }
 8 
 9   public class ConcreteCreator
10   {
11     public virtual AbstractOrInterfaceOfProduct CreateProduct(ProductCategory category)
12     {
13       switch (category)
14       {
15         case ProductCategory.GoodProduct:
16           return new ConcreteGoodProduct();
17         case ProductCategory.BadProduct:
18           return new ConcreteBadProduct();
19         default:
20           throw new NotSupportedException();
21       }
22     }
23   }
24 
25   public abstract class AbstractOrInterfaceOfProduct
26   {
27   }
28 
29   public class ConcreteGoodProduct : AbstractOrInterfaceOfProduct
30   {
31   }
32 
33   public class ConcreteBadProduct : AbstractOrInterfaceOfProduct
34   {
35   }
36 
37   public partial class Test
38   {
39     public void Case3()
40     {
41       ConcreteCreator creator = new ConcreteCreator();
42       AbstractOrInterfaceOfProduct product = creator.CreateProduct(ProductCategory.GoodProduct);
43     }
44   }
45 }

實現方式(四):使用模板以避免創建子類。

使用C#中的泛型實現工廠方法。

 1 namespace FactoryMethodPattern.Implementation4
 2 {
 3   public abstract class AbstractOrInterfaceOfCreator
 4   {
 5     public abstract AbstractOrInterfaceOfProduct CreateProduct();
 6   }
 7 
 8   public class GenericConcreteCreator<T> : AbstractOrInterfaceOfCreator
 9     where T : AbstractOrInterfaceOfProduct, new()
10   {
11     public AbstractOrInterfaceOfProduct CreateProduct()
12     {
13       return new T();
14     }
15   }
16 
17   public abstract class AbstractOrInterfaceOfProduct
18   {
19   }
20 
21   public class ConcreteGoodProduct : AbstractOrInterfaceOfProduct
22   {
23   }
24 
25   public class ConcreteBadProduct : AbstractOrInterfaceOfProduct
26   {
27   }
28 
29   public partial class Test
30   {
31     public void Case3()
32     {
33       AbstractOrInterfaceOfCreator creator1 = new GenericConcreteCreator<ConcreteGoodProduct>();
34       AbstractOrInterfaceOfCreator creator2 = new GenericConcreteCreator<ConcreteBadProduct>();
35       AbstractOrInterfaceOfProduct product1 = creator1.CreateProduct();
36       AbstractOrInterfaceOfProduct product2 = creator2.CreateProduct();
37     }
38   }
39 }

設計模式之美》為 Dennis Gao 發布于博客園的系列文章,任何未經作者本人同意的人為或爬蟲轉載均為耍流氓。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

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