Skip to content

Commit db669ae

Browse files
authored
Merge pull request #1 from refs/creational/abstract-factory
apply pr-97 from
2 parents f978e42 + e05b860 commit db669ae

File tree

3 files changed

+130
-2
lines changed

3 files changed

+130
-2
lines changed

Diff for: README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ A curated collection of idiomatic design & application patterns for Go language.
1515

1616
| Pattern | Description | Status |
1717
|:-------:|:----------- |:------:|
18-
| [Abstract Factory](/creational/abstract_factory.md) | Provides an interface for creating families of releated objects ||
18+
| [Abstract Factory](/creational/abstract-factory.md) | Provides an interface for creating families of releated objects ||
1919
| [Builder](/creational/builder.md) | Builds a complex object using simple objects ||
2020
| [Factory Method](/creational/factory.md) | Defers instantiation of an object to a specialized function for creating instances ||
2121
| [Object Pool](/creational/object-pool.md) | Instantiates and maintains a group of objects instances of the same type ||

Diff for: SUMMARY.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
* [Go Patterns](/README.md)
44
* [Creational Patterns](/README.md#creational-patterns)
5-
* [Abstract Factory](/creational/abstract_factory.md)
5+
* [Abstract Factory](/creational/abstract-factory.md)
66
* [Builder](/creational/builder.md)
77
* [Factory Method](/creational/factory.md)
88
* [Object Pool](/creational/object-pool.md)

Diff for: creational/abstract-factory.md

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Abstract Factory Method Pattern
2+
3+
Abstract Factory is a creational design pattern that allows you to create a _collection of related objects_.
4+
It provides an extra level of indirection over the [factory design pattern](factory.md).
5+
Using this pattern you can decouple the factory from your client code.
6+
7+
## Implementation
8+
9+
The example implementation shows how to create a collection (top & bottom) of summer clothes or winter clothes.
10+
11+
### Types
12+
13+
We begin with the simplest interfaces to represent a top or bottom article of clothing. Our items of clothing are [Stringer](https://tour.golang.org/methods/17) types.
14+
15+
```go
16+
package main
17+
18+
import "fmt"
19+
20+
type Top interface {
21+
String() string
22+
}
23+
24+
type Bottom interface {
25+
String() string
26+
}
27+
```
28+
29+
Next we introduce a couple of tops and bottoms into our system.
30+
31+
```go
32+
type TankTop struct {
33+
}
34+
35+
func (top TankTop) String() string {
36+
return "Tank Top"
37+
}
38+
39+
type Shorts struct {
40+
}
41+
42+
func (bottom Shorts) String() string {
43+
return "Shorts"
44+
}
45+
46+
type Sweater struct {
47+
}
48+
49+
func (top Sweater) String() string {
50+
return "Sweater"
51+
}
52+
53+
type WoolenPant struct {
54+
}
55+
56+
func (bottom WoolenPant) String() string {
57+
return "Woolen Pant"
58+
}
59+
60+
```
61+
62+
Next we create an interface to manage the _relatedness_ of clothes (summery or wintery)
63+
64+
```go
65+
type ClothesFactory interface {
66+
GetTop() Top
67+
GetBottom() Bottom
68+
}
69+
```
70+
71+
We give concrete implementations to this interface and bring it all together.
72+
73+
```go
74+
type SummerClothesFactory struct {
75+
}
76+
77+
func (summer SummerClothesFactory) GetTop() Top {
78+
return TankTop{}
79+
}
80+
81+
func (summer SummerClothesFactory) GetBottom() Bottom {
82+
return Shorts{}
83+
}
84+
85+
type WinterClothesFactory struct {
86+
}
87+
88+
func (winter WinterClothesFactory) GetTop() Top {
89+
return Sweater{}
90+
}
91+
92+
func (winter WinterClothesFactory) GetBottom() Bottom {
93+
return WoolenPant{}
94+
}
95+
```
96+
97+
## Usage
98+
99+
```go
100+
type Wardrobe struct {
101+
clothesFactory ClothesFactory
102+
}
103+
104+
func NewWardrobe(factory ClothesFactory) *Wardrobe {
105+
return &Wardrobe{
106+
clothesFactory: factory,
107+
}
108+
}
109+
110+
func (wardrobe Wardrobe) GetTop() Top {
111+
return wardrobe.clothesFactory.GetTop()
112+
}
113+
114+
func (wardrobe Wardrobe) GetBottom() Bottom {
115+
return wardrobe.clothesFactory.GetBottom()
116+
}
117+
118+
119+
func main() {
120+
summerWardrobe := NewWardrobe(SummerClothesFactory{})
121+
fmt.Printf("Summer clothes are %s & %s", summerWardrobe.GetTop(), summerWardrobe.GetBottom())
122+
123+
fmt.Println()
124+
winterWardrobe := NewWardrobe(WinterClothesFactory{})
125+
fmt.Printf("Winter clothes are %s & %s", winterWardrobe.GetTop(), winterWardrobe.GetBottom())
126+
127+
}
128+
```

0 commit comments

Comments
 (0)