設計模式之美:Abstract Factory(抽象工廠)


索引

別名

  • Kit

意圖

提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。

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

結構

參與者

AbstractFactory

  • 聲明一個創建抽象產品對象的操作接口。

ConcreteFactory

  • 實現創建具體產品對象的操作。

AbstractProduct

  • 為一類產品對象聲明一個接口。

ConcreteProduct

  • 定義一個將被相應的具體工廠創建的產品對象。
  • 實現 AbstractProduct 接口。

Client

  • 僅適用由 AbstractFactory 和 AbstractProduct 類聲明的接口。

適用性

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

  • 一個系統要獨立於它的產品的創建、組合和表示時。
  • 一個系統要由多個產品系列中的一個來配置時。
  • 當你要強調一系列相關的產品對象的設計以便進行聯合使用時。
  • 當你提供一個產品類庫,而只想顯示它們的接口而不是實現時。

缺點

  • 難以支持新種類的產品。支持新種類的產品就需要擴展 AbstractFactory 接口,這將引起所有子類的改變。

效果

  • 它分離了具體的類。
  • 它使得易於交換產品系列。
  • 它有利於產品的一致性。

相關模式

命名約定

使用命名約定是一個好習慣,例如,總是聲明那些定義為抽象工廠的類為 XxxKit。

實現

實現方式(一):使用 Factory Method 來實現 Abstract Factory。

一個具體的工廠將為每個產品重定義該工廠方法以指定產品。

 1 namespace AbstractFactoryPattern.Implementation1
 2 {
 3   public abstract class AbstractOrInterfaceOfFactoryKit
 4   {
 5     public abstract AbstractOrInterfaceOfProductA CreateProductA();
 6     public abstract AbstractOrInterfaceOfProductB CreateProductB();
 7   }
 8 
 9   public abstract class AbstractOrInterfaceOfProductA
10   {
11   }
12 
13   public abstract class AbstractOrInterfaceOfProductB
14   {
15   }
16 
17   public class ConcreteFactoryKit1 : AbstractOrInterfaceOfFactoryKit
18   {
19     public override AbstractOrInterfaceOfProductA CreateProductA()
20     {
21       return new ConcreteProductA();
22     }
23 
24     public override AbstractOrInterfaceOfProductB CreateProductB()
25     {
26       return new ConcreteProductB();
27     }
28   }
29 
30   public class ConcreteProductA : AbstractOrInterfaceOfProductA
31   {
32   }
33 
34   public class ConcreteProductB : AbstractOrInterfaceOfProductB
35   {
36   }
37 
38   public class Client
39   {
40     public void TestCase1()
41     {
42       AbstractOrInterfaceOfFactoryKit kit = new ConcreteFactoryKit1();
43       AbstractOrInterfaceOfProductA productA = kit.CreateProductA();
44       AbstractOrInterfaceOfProductB productB = kit.CreateProductB();
45     }
46   }
47 }

實現方式(二):使用 Prototype 來實現 Abstract Factory。

具體工廠使用產品系列中每一個產品的原型實例來初始化,且它通過復制它的原型來創建新的產品。

 1 namespace AbstractFactoryPattern.Implementation2
 2 {
 3   public abstract class AbstractOrInterfaceOfFactoryKit
 4   {
 5     public abstract AbstractOrInterfaceOfProductA CreateProductA();
 6     public abstract AbstractOrInterfaceOfProductB CreateProductB();
 7   }
 8 
 9   public abstract class AbstractOrInterfaceOfProductA
10   {
11     public abstract AbstractOrInterfaceOfProductA Clone();
12   }
13 
14   public abstract class AbstractOrInterfaceOfProductB
15   {
16     public abstract AbstractOrInterfaceOfProductB Clone();
17   }
18 
19   public class ConcreteFactoryKit1 : AbstractOrInterfaceOfFactoryKit
20   {
21     public override AbstractOrInterfaceOfProductA CreateProductA()
22     {
23       return new ConcreteProductA();
24     }
25 
26     public override AbstractOrInterfaceOfProductB CreateProductB()
27     {
28       return new ConcreteProductB();
29     }
30   }
31 
32   public class ConcreteFactoryKit2 : AbstractOrInterfaceOfFactoryKit
33   {
34     private AbstractOrInterfaceOfProductA _prototypeOfProductA;
35     private AbstractOrInterfaceOfProductB _prototypeOfProductB;
36 
37     public ConcreteFactoryKit2(
38       AbstractOrInterfaceOfProductA prototypeOfProductA,
39       AbstractOrInterfaceOfProductB prototypeOfProductB)
40     {
41       _prototypeOfProductA = prototypeOfProductA;
42       _prototypeOfProductB = prototypeOfProductB;
43     }
44 
45     public override AbstractOrInterfaceOfProductA CreateProductA()
46     {
47       return _prototypeOfProductA.Clone();
48     }
49 
50     public override AbstractOrInterfaceOfProductB CreateProductB()
51     {
52       return _prototypeOfProductB.Clone();
53     }
54   }
55 
56   public class ConcreteProductA : AbstractOrInterfaceOfProductA
57   {
58     public override AbstractOrInterfaceOfProductA Clone()
59     {
60       return new ConcreteProductA();
61     }
62   }
63 
64   public class ConcreteProductB : AbstractOrInterfaceOfProductB
65   {
66     public override AbstractOrInterfaceOfProductB Clone()
67     {
68       return new ConcreteProductB();
69     }
70   }
71 
72   public class Client
73   {
74     public void TestCase2()
75     {
76       AbstractOrInterfaceOfFactoryKit kit1 = new ConcreteFactoryKit1();
77       AbstractOrInterfaceOfProductA productA1 = kit1.CreateProductA();
78       AbstractOrInterfaceOfProductB productB1 = kit1.CreateProductB();
79 
80       AbstractOrInterfaceOfFactoryKit kit2 = new ConcreteFactoryKit2(productA1, productB1);
81       AbstractOrInterfaceOfProductA productA2 = kit2.CreateProductA();
82       AbstractOrInterfaceOfProductB productB2 = kit2.CreateProductB();
83     }
84   }
85 }

實現方式(三):定義可擴展的 Abstract Factory

Abstract Factory 通常為每一種它可以生產的產品定義一個操作。產品的種類被編碼在操作型構中。

增加一種新的產品要求改變 Abstract Factory 的接口以及所有與它相關的類。

一個更靈活但不太安全的設計是給創建對象的操作增加一個參數。該參數指定了將被創建的對象的種類。

該參數可以是一個類標識符、一個整數、一個字符串,或其他任何可以標識這種產品的東西。

這樣改動之后,Abstract Factory 只需要一個 "Make" 操作和一個指示要創建對象的種類的參數。

 1 namespace AbstractFactoryPattern.Implementation3
 2 {
 3   public enum ProductCategory
 4   {
 5     ProductA,
 6     ProductB,
 7   }
 8 
 9   public abstract class AbstractOrInterfaceOfFactoryKit
10   {
11     public abstract object CreateProduct(ProductCategory category);
12   }
13 
14   public abstract class AbstractOrInterfaceOfProductA
15   {
16   }
17 
18   public abstract class AbstractOrInterfaceOfProductB
19   {
20   }
21 
22   public class ConcreteFactoryKit1 : AbstractOrInterfaceOfFactoryKit
23   {
24     public override object CreateProduct(ProductCategory category)
25     {
26       switch (category)
27       {
28         case ProductCategory.ProductA:
29           return new ConcreteProductA();
30         case ProductCategory.ProductB:
31           return new ConcreteProductB();
32         default:
33           throw new NotSupportedException();
34       }
35     }
36   }
37 
38   public class ConcreteProductA : AbstractOrInterfaceOfProductA
39   {
40   }
41 
42   public class ConcreteProductB : AbstractOrInterfaceOfProductB
43   {
44   }
45 
46   public class Client
47   {
48     public void TestCase3()
49     {
50       AbstractOrInterfaceOfFactoryKit kit = new ConcreteFactoryKit1();
51       AbstractOrInterfaceOfProductA productA = (AbstractOrInterfaceOfProductA)kit.CreateProduct(ProductCategory.ProductA);
52       AbstractOrInterfaceOfProductB productB = (AbstractOrInterfaceOfProductB)kit.CreateProduct(ProductCategory.ProductB);
53     }
54   }
55 }

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

使用C#中的泛型實現抽象工廠。

 1 namespace AbstractFactoryPattern.Implementation4
 2 {
 3   public abstract class AbstractOrInterfaceOfFactoryKit
 4   {
 5     public abstract AbstractOrInterfaceOfProductA CreateProductA();
 6     public abstract AbstractOrInterfaceOfProductB CreateProductB();
 7     public abstract AbstractOrInterfaceOfProductC CreateProductC<TC>()
 8       where TC : AbstractOrInterfaceOfProductC, new();
 9   }
10 
11   public abstract class AbstractOrInterfaceOfProductA
12   {
13   }
14 
15   public abstract class AbstractOrInterfaceOfProductB
16   {
17   }
18 
19   public abstract class AbstractOrInterfaceOfProductC
20   {
21   }
22 
23   public class ConcreteFactoryKit1<TA, TB> : AbstractOrInterfaceOfFactoryKit
24     where TA : AbstractOrInterfaceOfProductA, new()
25     where TB : AbstractOrInterfaceOfProductB, new()
26   {
27     public override AbstractOrInterfaceOfProductA CreateProductA()
28     {
29       return new TA();
30     }
31 
32     public override AbstractOrInterfaceOfProductB CreateProductB()
33     {
34       return new TB();
35     }
36 
37     public override AbstractOrInterfaceOfProductC CreateProductC<TC>()
38     {
39       return new TC();
40     }
41   }
42 
43   public class ConcreteProductA : AbstractOrInterfaceOfProductA
44   {
45   }
46 
47   public class ConcreteProductB : AbstractOrInterfaceOfProductB
48   {
49   }
50 
51   public class ConcreteProductC : AbstractOrInterfaceOfProductC
52   {
53   }
54 
55   public class Client
56   {
57     public void TestCase4()
58     {
59       AbstractOrInterfaceOfFactoryKit kit = new ConcreteFactoryKit1<ConcreteProductA, ConcreteProductB>();
60       AbstractOrInterfaceOfProductA productA = kit.CreateProductA();
61       AbstractOrInterfaceOfProductB productB = kit.CreateProductB();
62       AbstractOrInterfaceOfProductC productC = kit.CreateProductC<ConcreteProductC>();
63     }
64   }
65 }

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM