Definition:
- Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
- A hierarchy that encapsulates: many possible “platforms”, and the construction of a suite of “products”.
- The new operator considered harmful.
Where to use & benefits
- Creates families of related or dependent objects like Kit.
- Provides a class library of products, exposing interface not implementation.
- Needs to isolate concrete classes from their super classes.
- A system needs independent of how its products are created, composed, and represented.
- Try to enforce a constraint.
- An alternative to Facade to hide platform-specific classe.
- Easily extensible to a system or a family.
- Related patterns include.
- Factory method, which is often implemented with an abstract factory.
- Singleton, which is often implemented with an abstract factory.
- Prototype, which is often implemented with an abstract factory.
- Facade, which is often used with an abstract factory by providing an interface for creating implementing class.
This pattern is one level of abstraction higher than factory pattern. This means that the abstract factory returns the factory of classes. Like Factory pattern returned one of the several sub-classes, this returns such factory which later will return one of the sub-classes.
Working with Abstract Factory Design Pattern
The classes that participate to the Abstract Factory pattern are:
AbstractFactory - declares a interface for operations that create abstract products.
ConcreteFactory - implements operations to create concrete products.
AbstractProduct - declares an interface for a type of product objects.
Product - defines a product to be created by the corresponding ConcreteFactory; it implements the AbstractProduct interface.
Client - uses the interfaces declared by the AbstractFactory and AbstractProduct classes.
Working with Abstract Factory Design Pattern
The classes that participate to the Abstract Factory pattern are:
AbstractFactory - declares a interface for operations that create abstract products.
ConcreteFactory - implements operations to create concrete products.
AbstractProduct - declares an interface for a type of product objects.
Product - defines a product to be created by the corresponding ConcreteFactory; it implements the AbstractProduct interface.
Client - uses the interfaces declared by the AbstractFactory and AbstractProduct classes.
The classic implementation for the Abstract Factory pattern is the following:
<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;color:black;background:white;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><table><tr><td><pre style="margin: 0; line-height: 125%"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83</pre></td><td><pre style="margin: 0; line-height: 125%"><span style="color: #008000; font-weight: bold">package</span> com<span style="color: #303030">.</span><span style="color: #0000C0">kota</span><span style="color: #303030">.</span><span style="color: #0000C0">java</span><span style="color: #303030">;</span>
<span style="color: #008000; font-weight: bold">abstract</span> <span style="color: #008000; font-weight: bold">class</span> <span style="color: #B00060; font-weight: bold">AbstractProductA</span><span style="color: #303030">{</span>
<span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">abstract</span> <span style="color: #303090; font-weight: bold">void</span> <span style="color: #0060B0; font-weight: bold">operationA1</span><span style="color: #303030">();</span>
<span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">abstract</span> <span style="color: #303090; font-weight: bold">void</span> <span style="color: #0060B0; font-weight: bold">operationA2</span><span style="color: #303030">();</span>
<span style="color: #303030">}</span>
<span style="color: #008000; font-weight: bold">class</span> <span style="color: #B00060; font-weight: bold">ProductA1</span> <span style="color: #008000; font-weight: bold">extends</span> AbstractProductA<span style="color: #303030">{</span>
ProductA1<span style="color: #303030">(</span>String arg<span style="color: #303030">){</span>
System<span style="color: #303030">.</span><span style="color: #0000C0">out</span><span style="color: #303030">.</span><span style="color: #0000C0">println</span><span style="color: #303030">(</span><span style="background-color: #fff0f0">"Hello "</span><span style="color: #303030">+</span>arg<span style="color: #303030">);</span>
<span style="color: #303030">}</span> <span style="color: #808080">// Implement the code here</span>
<span style="color: #008000; font-weight: bold">public</span> <span style="color: #303090; font-weight: bold">void</span> <span style="color: #0060B0; font-weight: bold">operationA1</span><span style="color: #303030">()</span> <span style="color: #303030">{</span> <span style="color: #303030">};</span>
<span style="color: #008000; font-weight: bold">public</span> <span style="color: #303090; font-weight: bold">void</span> <span style="color: #0060B0; font-weight: bold">operationA2</span><span style="color: #303030">()</span> <span style="color: #303030">{</span> <span style="color: #303030">};</span>
<span style="color: #303030">}</span>
<span style="color: #008000; font-weight: bold">class</span> <span style="color: #B00060; font-weight: bold">ProductA2</span> <span style="color: #008000; font-weight: bold">extends</span> AbstractProductA<span style="color: #303030">{</span>
ProductA2<span style="color: #303030">(</span>String arg<span style="color: #303030">){</span>
System<span style="color: #303030">.</span><span style="color: #0000C0">out</span><span style="color: #303030">.</span><span style="color: #0000C0">println</span><span style="color: #303030">(</span><span style="background-color: #fff0f0">"Hello "</span><span style="color: #303030">+</span>arg<span style="color: #303030">);</span>
<span style="color: #303030">}</span> <span style="color: #808080">// Implement the code here</span>
<span style="color: #008000; font-weight: bold">public</span> <span style="color: #303090; font-weight: bold">void</span> <span style="color: #0060B0; font-weight: bold">operationA1</span><span style="color: #303030">()</span> <span style="color: #303030">{</span> <span style="color: #303030">};</span>
<span style="color: #008000; font-weight: bold">public</span> <span style="color: #303090; font-weight: bold">void</span> <span style="color: #0060B0; font-weight: bold">operationA2</span><span style="color: #303030">()</span> <span style="color: #303030">{</span> <span style="color: #303030">};</span>
<span style="color: #303030">}</span>
<span style="color: #008000; font-weight: bold">abstract</span> <span style="color: #008000; font-weight: bold">class</span> <span style="color: #B00060; font-weight: bold">AbstractProductB</span><span style="color: #303030">{</span>
<span style="color: #808080">//public abstract void operationB1();</span>
<span style="color: #808080">//public abstract void operationB2();</span>
<span style="color: #303030">}</span>
<span style="color: #008000; font-weight: bold">class</span> <span style="color: #B00060; font-weight: bold">ProductB1</span> <span style="color: #008000; font-weight: bold">extends</span> AbstractProductB<span style="color: #303030">{</span>
ProductB1<span style="color: #303030">(</span>String arg<span style="color: #303030">){</span>
System<span style="color: #303030">.</span><span style="color: #0000C0">out</span><span style="color: #303030">.</span><span style="color: #0000C0">println</span><span style="color: #303030">(</span><span style="background-color: #fff0f0">"Hello "</span><span style="color: #303030">+</span>arg<span style="color: #303030">);</span>
<span style="color: #303030">}</span> <span style="color: #808080">// Implement the code here</span>
<span style="color: #303030">}</span>
<span style="color: #008000; font-weight: bold">class</span> <span style="color: #B00060; font-weight: bold">ProductB2</span> <span style="color: #008000; font-weight: bold">extends</span> AbstractProductB<span style="color: #303030">{</span>
ProductB2<span style="color: #303030">(</span>String arg<span style="color: #303030">){</span>
System<span style="color: #303030">.</span><span style="color: #0000C0">out</span><span style="color: #303030">.</span><span style="color: #0000C0">println</span><span style="color: #303030">(</span><span style="background-color: #fff0f0">"Hello "</span><span style="color: #303030">+</span>arg<span style="color: #303030">);</span>
<span style="color: #303030">}</span> <span style="color: #808080">// Implement the code here</span>
<span style="color: #303030">}</span>
<span style="color: #008000; font-weight: bold">abstract</span> <span style="color: #008000; font-weight: bold">class</span> <span style="color: #B00060; font-weight: bold">AbstractFactory</span><span style="color: #303030">{</span>
<span style="color: #008000; font-weight: bold">abstract</span> AbstractProductA <span style="color: #0060B0; font-weight: bold">createProductA</span><span style="color: #303030">();</span>
<span style="color: #008000; font-weight: bold">abstract</span> AbstractProductB <span style="color: #0060B0; font-weight: bold">createProductB</span><span style="color: #303030">();</span>
<span style="color: #303030">}</span>
<span style="color: #008000; font-weight: bold">class</span> <span style="color: #B00060; font-weight: bold">ConcreteFactory1</span> <span style="color: #008000; font-weight: bold">extends</span> AbstractFactory<span style="color: #303030">{</span>
AbstractProductA <span style="color: #0060B0; font-weight: bold">createProductA</span><span style="color: #303030">(){</span>
<span style="color: #008000; font-weight: bold">return</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #0060B0; font-weight: bold">ProductA1</span><span style="color: #303030">(</span><span style="background-color: #fff0f0">"ProductA1"</span><span style="color: #303030">);</span>
<span style="color: #303030">}</span>
AbstractProductB <span style="color: #0060B0; font-weight: bold">createProductB</span><span style="color: #303030">(){</span>
<span style="color: #008000; font-weight: bold">return</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #0060B0; font-weight: bold">ProductB1</span><span style="color: #303030">(</span><span style="background-color: #fff0f0">"ProductB1"</span><span style="color: #303030">);</span>
<span style="color: #303030">}</span>
<span style="color: #303030">}</span>
<span style="color: #008000; font-weight: bold">class</span> <span style="color: #B00060; font-weight: bold">ConcreteFactory2</span> <span style="color: #008000; font-weight: bold">extends</span> AbstractFactory<span style="color: #303030">{</span>
AbstractProductA <span style="color: #0060B0; font-weight: bold">createProductA</span><span style="color: #303030">(){</span>
<span style="color: #008000; font-weight: bold">return</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #0060B0; font-weight: bold">ProductA2</span><span style="color: #303030">(</span><span style="background-color: #fff0f0">"ProductA2"</span><span style="color: #303030">);</span>
<span style="color: #303030">}</span>
AbstractProductB <span style="color: #0060B0; font-weight: bold">createProductB</span><span style="color: #303030">(){</span>
<span style="color: #008000; font-weight: bold">return</span> <span style="color: #008000; font-weight: bold">new</span> <span style="color: #0060B0; font-weight: bold">ProductB2</span><span style="color: #303030">(</span><span style="background-color: #fff0f0">"ProductB2"</span><span style="color: #303030">);</span>
<span style="color: #303030">}</span>
<span style="color: #303030">}</span>
<span style="color: #808080">//Factory creator - an indirect way of instantiating the factories</span>
<span style="color: #008000; font-weight: bold">class</span> <span style="color: #B00060; font-weight: bold">FactoryMaker</span><span style="color: #303030">{</span>
<span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">static</span> AbstractFactory pf<span style="color: #303030">=</span><span style="color: #008000; font-weight: bold">null</span><span style="color: #303030">;</span>
<span style="color: #008000; font-weight: bold">static</span> AbstractFactory <span style="color: #0060B0; font-weight: bold">getFactory</span><span style="color: #303030">(</span>String choice<span style="color: #303030">){</span>
<span style="color: #008000; font-weight: bold">if</span><span style="color: #303030">(</span>choice<span style="color: #303030">.</span><span style="color: #0000C0">equals</span><span style="color: #303030">(</span><span style="background-color: #fff0f0">"a"</span><span style="color: #303030">)){</span>
pf<span style="color: #303030">=</span><span style="color: #008000; font-weight: bold">new</span> ConcreteFactory1<span style="color: #303030">();</span>
<span style="color: #303030">}</span><span style="color: #008000; font-weight: bold">else</span> <span style="color: #008000; font-weight: bold">if</span><span style="color: #303030">(</span>choice<span style="color: #303030">.</span><span style="color: #0000C0">equals</span><span style="color: #303030">(</span><span style="background-color: #fff0f0">"b"</span><span style="color: #303030">)){</span>
pf<span style="color: #303030">=</span><span style="color: #008000; font-weight: bold">new</span> ConcreteFactory2<span style="color: #303030">();</span>
<span style="color: #303030">}</span> <span style="color: #008000; font-weight: bold">return</span> pf<span style="color: #303030">;</span>
<span style="color: #303030">}</span>
<span style="color: #303030">}</span>
<span style="color: #808080">// Client</span>
<span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">class</span> <span style="color: #B00060; font-weight: bold">Client</span><span style="color: #303030">{</span>
<span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">static</span> <span style="color: #303090; font-weight: bold">void</span> <span style="color: #0060B0; font-weight: bold">main</span><span style="color: #303030">(</span>String args<span style="color: #303030">[]){</span>
AbstractFactory pf<span style="color: #303030">=</span>FactoryMaker<span style="color: #303030">.</span><span style="color: #0000C0">getFactory</span><span style="color: #303030">(</span><span style="background-color: #fff0f0">"a"</span><span style="color: #303030">);</span>
AbstractProductA product<span style="color: #303030">=</span>pf<span style="color: #303030">.</span><span style="color: #0000C0">createProductA</span><span style="color: #303030">();</span>
<span style="color: #808080">//more function calls on product</span>
<span style="color: #303030">}</span>
<span style="color: #303030">}</span>
</pre></td></tr></table></div>
Very informative and worthy post. Thanks for the sharing such a precious updates with us.
ReplyDeleteSamsung - Series 5 Ultrabook 13.3" Touch-Screen Laptop - 4GB Memory - 500GB Hard Drive - Titan Silver
Samsung - ATIV Smart PC Pro 700T Tablet with 128GB Memory - Black