python建造者模式
class AppleFactory:
class MacMini14:
def __init__(self):
self.memory = 4 # 单位为GB
self.hdd = 500 # 单位为GB
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 dont't know how to build {}".format(model))
if __name__ == '__main__':
MINI14 = '1.4GHz Mac mini'
afac = AppleFactory()
mac_mini = afac.build_computer(MINI14)
print(mac_mini)
如果我们知道一个对象必须经过多个步骤来创建,并且要求同一个构造过程可以产生不同的
表现,就可以使用建造者模式。这种需求存在于许多应用中,例如页面生成器(本章提到的HTML
页面生成器之类)、文档转换器以及用户界面(User Interface,UI)表单创建工具。
有些资料提到建造者模式也可用于解决可伸缩构造函数问题。
当我们为支持不同的对象创建方式而不得不创建一个新的构造函数时,可伸缩构造函数问题就发
生了,这种情况最终产生许多构造函数和长长的形参列表,难以管理。Stack Overflow网站上列
出了一个可伸缩构造函数的例子。幸运的是,这个问题在Python
中并不存在,因为至少有以下两种方式可以解决这个问题。
使用命名形参
使用实参列表展开
在这一点上,建造者模式和工厂模式的差别并不太明确。主要的区别在于工厂模式以单个步
骤创建对象,而建造者模式以多个步骤创建对象,并且几乎始终会使用一个指挥者。一些有针对
性的建造者模式实现并未使用指挥者,如Java的StringBuilder,但这只是例外。
另一个区别是,在工厂模式下,会立即返回一个创建好的对象;而在建造者模式下,仅在需
要时客户端代码才显式地请求指挥者返回最终的对象。
新电脑类比的例子也许有助于区分建造者模式和工厂模式。假设你想购买一台新电脑,如果
决定购买一台特定的预配置的电脑型号,例如,最新的苹果1.4GHz Mac mini,则是在使用工厂
模式。所有硬件的规格都已经由制造商预先确定,制造商不用向你咨询就知道自己该做些什么,
它们通常接收的仅仅是单条指令。
class Computer:
def __init__(self, serial_number):
self.serial = serial_number
self.memory = None # 单位为GB
self.hdd = None # 单位为GB
self.gpu = None
def __str__(self):
info = ('Memory: {}GB'.format(self.memory),
'Hard Disk: {}GB'.format(self.hdd),
'Graphics Card: {}'.format(self.gpu))
return '\n'.join(info)
class ComputerBuilder:
def __init__(self):
self.computer = Computer('AG23385193')
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
def main():
engineer = HardwareEngineer()
engineer.construct_computer(hdd=500, memory=8, gpu='GeForce GTX 650 Ti')
computer = engineer.computer
print(computer)
if __name__ == '__main__':
main()