Repository navigation
Expand file tree
/
Copy pathabstract_factory.py
More file actions
80 lines (54 loc) · 1.75 KB
/
Copy pathabstract_factory.py
File metadata and controls
80 lines (54 loc) · 1.75 KB
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
"""
Abstract Factory — families of products that belong together
A `Theme` factory produces a matching `Button` and `Checkbox`.
`LightTheme` yields light widgets, `DarkTheme` yields dark ones. The
`Form` asks its theme for parts and gets a coherent set — it never
mixes a light button with a dark checkbox, because it never names a
concrete widget class.
Compare with the procedural Python version:
if theme == "dark":
button = DarkButton()
checkbox = DarkCheckbox()
else:
button = LightButton()
checkbox = LightCheckbox()
POOP forbids that branching. The factory object encapsulates the whole
family; swap the factory and every part changes together.
Smalltalk:
LightTheme>>button ^LightButton new
LightTheme>>checkbox ^LightCheckbox new
DarkTheme>>button ^DarkButton new
DarkTheme>>checkbox ^DarkCheckbox new
Form>>render
^{ theme button render. theme checkbox render }
"""
class LightButton:
def render(self):
return "[ OK ] (light)"
class DarkButton:
def render(self):
return "[ OK ] (dark)"
class LightCheckbox:
def render(self):
return "[x] (light)"
class DarkCheckbox:
def render(self):
return "[x] (dark)"
class LightTheme:
def button(self):
return LightButton()
def checkbox(self):
return LightCheckbox()
class DarkTheme:
def button(self):
return DarkButton()
def checkbox(self):
return DarkCheckbox()
class Form:
def __init__(self, theme):
self._theme = theme
def render(self):
return [self._theme.button().render(), self._theme.checkbox().render()]
[LightTheme(), DarkTheme()].do(
lambda theme: Form(theme).render().do(lambda part: part.print())
)