【建造者模式】

问题

1、创建的对象复杂,需要由多个部分组成,且这些这些部分需要按照特定顺序完成
2、希望构造与表示解耦

建造者模式

可以创建一个由多个部分(这些部分按特定顺序完成)组成的对象

Demo

背景&&需求

披萨订购应用程序
支持订购2种披萨:Margarita披萨、CreamyBacon披萨
制作披萨需4个步骤:1、准备面团;2、加调味汁;3、加配料;4、烤

代码

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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# !/usr/bin/python3
# -*- coding: utf-8 -*-
from enum import Enum
import time


class PizzaProgress(Enum):
queued = 1
preparation = 2
baking = 3
ready = 4


class PizzaDough(Enum):
thin = 1 # 薄的
thick = 2 # 厚的


class PizzaSauce(Enum):
tomato = 1
creme_fraiche = 2


class PizzaTopping(Enum):
mozzarella = 1 # 奶酪
ham = 2 # 火腿
mushrooms = 3 # 蘑菇
double_mozzarella = 4
oregano = 5


class Pizza:
def __init__(self, name):
self.name = name
self.dough = None # 面团
self.sauce = None # 调味汁
self.topping = [] # 配料

def __str__(self):
return self.name


class MargaritaBuilder:
def __init__(self):
self.pizza = Pizza('margarita')
self.progress = PizzaProgress.queued
self.baking_time = 1 # 烤1s

def prepare_dough(self):
print('prepare dough for margarita')
self.progress = PizzaProgress.preparation
self.pizza.dough = PizzaDough.thin
print('done with dough')

def add_sauce(self):
print('add sauce to margarita')
self.pizza.sauce = PizzaSauce.tomato
print('done with sauce')

def add_topping(self):
print('add topping to margarita')
topping_items = [
PizzaTopping.double_mozzarella,
PizzaTopping.oregano
]
self.pizza.topping.append([item for item in topping_items])
print('done with topping')

def bake(self):
self.progress = PizzaProgress.baking
print('baking margarita...')
time.sleep(self.baking_time)
self.progress = PizzaProgress.ready
print('margarita ready')


class CreamyBaconBuilder:
def __init__(self):
self.pizza = Pizza('creamy bacon')
self.progress = PizzaProgress.queued
self.baking_time = 2 # 烤2s

def prepare_dough(self):
print('prepare dough for creamy bacon')
self.progress = PizzaProgress.preparation
self.pizza.dough = PizzaDough.thick
print('done with dough')

def add_sauce(self):
print('add sauce to creamy bacon')
self.pizza.sauce = PizzaSauce.creme_fraiche
print('done with sauce')

def add_topping(self):
print('add topping to creamy bacon')
topping_items = [
PizzaTopping.mozzarella,
PizzaTopping.ham
]
self.pizza.topping.append([item for item in topping_items])
print('done with topping')

def bake(self):
self.progress = PizzaProgress.baking
print('baking creamy bacon...')
time.sleep(self.baking_time)
self.progress = PizzaProgress.ready
print('creamy bacon ready')


class Waiter:
def __init__(self):
self.builder = None

def construct_pizza(self, builder):
self.builder = builder
steps = [
builder.prepare_dough,
builder.add_sauce,
builder.add_topping,
builder.bake
]
[step() for step in steps]

@property
def pizza(self):
return self.builder.pizza


if __name__ == '__main__':
waiter = Waiter()
waiter.construct_pizza(MargaritaBuilder())
pizza = waiter.pizza
print(f'Enjoy {pizza}!')

print('-----------------------')

waiter.construct_pizza(CreamyBaconBuilder())
pizza = waiter.pizza
print(f'Enjoy {pizza}!')

输出

prepare dough for margarita
done with dough
add sauce to margarita
done with sauce
add topping to margarita
done with topping
baking margarita…
margarita ready
Enjoy margarita!


prepare dough for creamy bacon
done with dough
add sauce to creamy bacon
done with sauce
add topping to creamy bacon
done with topping
baking creamy bacon…
creamy bacon ready
Enjoy creamy bacon!