python设计模式:建造者模式

建造者模式(Builder Pattern) 又名生成器模式,是一种对象构建模式。它允许用户只需要指定复杂对象的类型就可以构建它们,而无须知道其内部的具体构造细节。
该模式适用于基本部件不变,而其组合经常变化的场景,例如购物、点餐。

组装电脑场景

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
class Computer:
def __init__(self, serial_number):
self.serial = serial_number
self.memory=None
self.hdd=None
self.gpu=None
def __str__(self):
info=('Memory: {}'.format(self.memory),
'Hard Disk: {}'.format(self.hdd),
'Graphics Card: {}'.format(self.gpu))
return '\n'.join(info)

class ComputerBuilder:
def __init__(self):
self.computer=Computer('AG0234532')

def configure_memory(self, amount):
self.computer.memory=amount
def configure_hdd(self, amount):
self.computer.hdd=amount
def configure_gpu(self, gpu_model):
self.computer.gpu=gpu_model

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

def construct_computer(self, memory, hdd, gpu):
self.builder = ComputerBuilder()
[step for step in (self.builder.configure_memory(memory),
self.builder.configure_hdd(hdd),
self.builder.configure_gpu(gpu))]
@property
def computer(self):
return self.builder.computer

if __name__ == '__main__':
engineer = HardwareEngineer()
engineer.construct_computer(hdd=500, memory=8, gpu='GeForce GTX 650 Ti')
computer = engineer.computer
print(computer)

如果换成工厂模式是什么样子呢?
所有硬件的规格都已经由制造商预先确定,制造商不用向你咨询就知道自己该做些什么,它们通常接收的仅仅是单条指令。

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
MINI14 = '1.4GHz Mac mini'

class AppleFactory:
class MacMini14:
def __init__(self):
self.memory=4
self.hdd=500
self.gpu='Intel HD Graphics 5000'
def __str__(self):
info=('Model: {}'.format(MINI14),
'Memory: {}GB'.format(self.memory),
'Hard Disk: {}GB'.format(self.hdd),
'Graphics Card: {}'.format(self.gpu))
return '\n'.join(info)

def build_computer(self,model):
if(model==MINI14):
return self.MacMini14()
else:
print("I don't know how to build {}".format(model))

if __name__ == '__main__':
afac = AppleFactory()
mac_mini = afac.build_computer(MINI14)
print(mac_mini)

订购披萨场景

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
class Pizza:
def __init__(self, builder):
self.garlic = builder.garlic
self.extra_cheese = builder.extra_cheese

def __str__(self):
garlic = 'yes' if self.garlic else 'no'
cheese = 'yes' if self.extra_cheese else 'no'
info = ('Garlic: {}'.format(garlic), 'Extra cheese: {}'.format(cheese))
return '\n'.join(info)

class PizzaBuilder:
def __init__(self):
self.extra_cheese = False
self.garlic = False

def add_garlic(self):
self.garlic = True
return self

def add_extra_cheese(self):
self.extra_cheese = True
return self

def build(self):
return Pizza(self)

if __name__ == '__main__':
pizza = Pizza.PizzaBuilder().add_garlic().add_extra_cheese().build()
print(pizza)