Abstract Factory
Definition
Provide an interface for creating families of related or dependent
objects without specifying their concrete classes.
UML class diagram
Participants
The classes and objects participating in this
pattern are:
- AbstractFactory (ContinentFactory)
- declares
an interface for operations that create abstract products
- ConcreteFactory (AfricaFactory, AmericaFactory)
- implements
the operations to create concrete product objects
- AbstractProduct (Herbivore, Carnivore)
- declares
an interface for a type of product object
- Product (Wildebeest,
Lion, Bison, Wolf)
- defines
a product object to be created by the corresponding concrete factory
- implements
the AbstractProduct interface
- Client (AnimalWorld)
- uses
interfaces declared by AbstractFactory and AbstractProduct classes
Structural code in
C#
This structural code demonstrates the Abstract Factory pattern creating parallel
hierarchies of objects. Object creation has been abstracted and there is no
need for hard-coded class names in the client code.
1.
2.
3.
4. using System;
5.
6. namespace DoFactory.GangOfFour.Abstract.Structural
7. {
8. /// <summary>
9. /// MainApp startup class for Structural
10. /// Abstract Factory Design Pattern.
11. /// </summary>
12. class MainApp
13. {
14. /// <summary>
15. /// Entry point into console application.
16. /// </summary>
17. public static void Main()
18. {
19. // Abstract factory #1
20. AbstractFactory factory1 = new ConcreteFactory1();
21. Client client1 = new Client(factory1);
22. client1.Run();
23.
24. // Abstract factory #2
25. AbstractFactory factory2 = new ConcreteFactory2();
26. Client client2 = new Client(factory2);
27. client2.Run();
28.
29. // Wait for user input
30. Console.ReadKey();
31. }
32. }
33.
34. /// <summary>
35. /// The 'AbstractFactory' abstract class
36. /// </summary>
37. abstract class AbstractFactory
38. {
39. public abstract AbstractProductA CreateProductA();
40. public abstract AbstractProductB CreateProductB();
41. }
42.
43.
44. /// <summary>
45. /// The 'ConcreteFactory1' class
46. /// </summary>
47. class ConcreteFactory1 : AbstractFactory
48. {
49. public override AbstractProductA CreateProductA()
50. {
51. return new ProductA1();
52. }
53. public override AbstractProductB CreateProductB()
54. {
55. return new ProductB1();
56. }
57. }
58.
59. /// <summary>
60. /// The 'ConcreteFactory2' class
61. /// </summary>
62. class ConcreteFactory2 : AbstractFactory
63. {
64. public override AbstractProductA CreateProductA()
65. {
66. return new ProductA2();
67. }
68. public override AbstractProductB CreateProductB()
69. {
70. return new ProductB2();
71. }
72. }
73.
74. /// <summary>
75. /// The 'AbstractProductA' abstract class
76. /// </summary>
77. abstract class AbstractProductA
78. {
79. }
80.
81. /// <summary>
82. /// The 'AbstractProductB' abstract class
83. /// </summary>
84. abstract class AbstractProductB
85. {
86. public abstract void Interact(AbstractProductA a);
87. }
88.
89.
90. /// <summary>
91. /// The 'ProductA1' class
92. /// </summary>
93. class ProductA1 : AbstractProductA
94. {
95. }
96.
97. /// <summary>
98. /// The 'ProductB1' class
99. /// </summary>
100.
class ProductB1 : AbstractProductB
101.
{
102.
public override void Interact(AbstractProductA a)
103.
{
104.
Console.WriteLine(this.GetType().Name +
105.
" interacts with " + a.GetType().Name);
106.
}
107.
}
108.
109.
/// <summary>
110.
/// The 'ProductA2' class
111.
/// </summary>
112.
class ProductA2 : AbstractProductA
113.
{
114.
}
115.
116.
/// <summary>
117.
/// The 'ProductB2' class
118.
/// </summary>
119.
class ProductB2 : AbstractProductB
120.
{
121.
public override void Interact(AbstractProductA a)
122.
{
123.
Console.WriteLine(this.GetType().Name +
124.
" interacts with " + a.GetType().Name);
125.
}
126.
}
127.
128.
/// <summary>
129.
/// The 'Client' class. Interaction
environment for the products.
130.
/// </summary>
131.
class Client
132.
{
133.
private AbstractProductA _abstractProductA;
134.
private AbstractProductB _abstractProductB;
135.
136.
// Constructor
137.
public Client(AbstractFactory factory)
138.
{
139.
_abstractProductB = factory.CreateProductB();
140.
_abstractProductA = factory.CreateProductA();
141.
}
142.
143.
public void Run()
144.
{
145.
_abstractProductB.Interact(_abstractProductA);
146.
}
147.
}
148.
}
149.
150.
151.
152.
Output
ProductB1 interacts with ProductA1
ProductB2 interacts with ProductA2
ProductB2 interacts with ProductA2
Real-world code in
C#
This real-world code demonstrates the creation of different animal worlds for a computer
game using different factories. Although the animals created by the Continent
factories are different, the interactions among the animals remain the same.
1.
2.
3. using System;
4.
5. namespace DoFactory.GangOfFour.Abstract.RealWorld
6. {
7. /// <summary>
8. /// MainApp startup class for Real-World
9. /// Abstract Factory Design Pattern.
10. /// </summary>
11. class MainApp
12. {
13. /// <summary>
14. /// Entry point into console application.
15. /// </summary>
16. public static void Main()
17. {
18. // Create and run the African animal world
19. ContinentFactory africa = new AfricaFactory();
20. AnimalWorld world = new AnimalWorld(africa);
21. world.RunFoodChain();
22.
23. // Create and run the American animal world
24. ContinentFactory america = new AmericaFactory();
25. world
= new AnimalWorld(america);
26. world.RunFoodChain();
27.
28. // Wait for user input
29. Console.ReadKey();
30. }
31. }
32.
33.
34. /// <summary>
35. /// The 'AbstractFactory' abstract class
36. /// </summary>
37. abstract class ContinentFactory
38. {
39. public abstract Herbivore CreateHerbivore();
40. public abstract Carnivore CreateCarnivore();
41. }
42.
43. /// <summary>
44. /// The 'ConcreteFactory1' class
45. /// </summary>
46. class AfricaFactory : ContinentFactory
47. {
48. public override Herbivore CreateHerbivore()
49. {
50. return new Wildebeest();
51. }
52. public override Carnivore CreateCarnivore()
53. {
54. return new Lion();
55. }
56. }
57.
58. /// <summary>
59. /// The 'ConcreteFactory2' class
60. /// </summary>
61. class AmericaFactory : ContinentFactory
62. {
63. public override Herbivore CreateHerbivore()
64. {
65. return new Bison();
66. }
67. public override Carnivore CreateCarnivore()
68. {
69. return new Wolf();
70. }
71. }
72.
73. /// <summary>
74. /// The 'AbstractProductA' abstract class
75. /// </summary>
76. abstract class Herbivore
77. {
78. }
79.
80. /// <summary>
81. /// The 'AbstractProductB' abstract class
82. /// </summary>
83. abstract class Carnivore
84. {
85. public abstract void Eat(Herbivore h);
86. }
87.
88. /// <summary>
89. /// The 'ProductA1' class
90. /// </summary>
91. class Wildebeest : Herbivore
92. {
93. }
94.
95. /// <summary>
96. /// The 'ProductB1' class
97. /// </summary>
98. class Lion : Carnivore
99. {
100.
public override void Eat(Herbivore h)
101.
{
102.
// Eat Wildebeest
103.
Console.WriteLine(this.GetType().Name +
104.
" eats " + h.GetType().Name);
105.
}
106.
}
107.
108.
/// <summary>
109.
/// The 'ProductA2' class
110.
/// </summary>
111.
class Bison : Herbivore
112.
{
113.
}
114.
115.
/// <summary>
116.
/// The 'ProductB2' class
117.
/// </summary>
118.
class Wolf : Carnivore
119.
{
120.
public override void Eat(Herbivore h)
121.
{
122.
// Eat Bison
123.
Console.WriteLine(this.GetType().Name +
124.
" eats " + h.GetType().Name);
125.
}
126.
}
127.
128.
/// <summary>
129.
/// The 'Client' class
130.
/// </summary>
131.
class AnimalWorld
132.
{
133.
private Herbivore _herbivore;
134.
private Carnivore _carnivore;
135.
136.
// Constructor
137.
public AnimalWorld(ContinentFactory factory)
138.
{
139.
_carnivore = factory.CreateCarnivore();
140.
_herbivore = factory.CreateHerbivore();
141.
}
142.
143.
public void RunFoodChain()
144.
{
145.
_carnivore.Eat(_herbivore);
146.
}
147.
}
148.
}
149.
150.
151.
Output
Lion eats Wildebeest
Wolf eats Bison
Wolf eats Bison

No comments:
Post a Comment