生成器模式是一种创建型设计模式, 使你能够分步骤创建复杂对象,生成器不允许其他对象访问正在创建中的产品。 该模式允许你使用相同的创建代码生成不同类型和形式的对象。又名建造者模式。
为什么需要?
简化复杂的构造函数。只有当产品较为复杂且需要详细配置时,使用生成器模式才有意义。生成器与其他创建型模式的不同之处在于:它让你能创建不遵循相同接口的产品。
应用场景
- 使用生成器模式可避免 “重叠构造函数 (telescopic constructor)” 的出现。
- 当希望使用代码创建不同形式的产品 (例如石头或木头房屋) 时, 可使用生成器模式。
- 使用生成器构造组合树或其他复杂对象。
实现方式
- 清晰地定义通用步骤, 确保它们可以制造所有形式的产品。 否则你将无法进一步实施该模式。
- 在基本生成器接口中声明这些步骤。
- 为每个形式的产品创建具体生成器类, 并实现其构造步骤。
- 不要忘记实现获取构造结果对象的方法。 你不能在生成器接口中声明该方法, 因为不同生成器构造的产品可能没有公共接口, 因此你就不知道该方法返回的对象类型。 但是, 如果所有产品都位于单一类层次中, 你就可以安全地在基本接口中添加获取生成对象的方法。
- 考虑创建主管类。 它可以使用同一生成器对象来封装多种构造产品的方式。
- 客户端代码会同时创建生成器和主管对象。 构造开始前, 客户端必须将生成器对象传递给主管对象。 通常情况下, 客户端只需调用主管类构造函数一次即可。 主管类使用生成器对象完成后续所有制造任务。 还有另一种方式, 那就是客户端可以将生成器对象直接传递给主管类的制造方法。
- 只有在所有产品都遵循相同接口的情况下, 构造结果可以直接通过主管类获取。 否则, 客户端应当通过生成器获取构造结果。
示例代码
from typing import Any
"""
一个电脑产品创建者,cpu是必须的
风扇和gpu是不一定需要的
"""
class Cpu():
def __init__(self):
self.type = ""
self.price = 0
def do_some_function(self):
print('cpu用来计算')
def __repr__(self):
return 'cpu'
class InterCpu(Cpu):
def __init__(self):
super(Cpu, self).__init__()
self.type = "英特尔i7"
self.price = 3000
class AMDCpu(Cpu):
def __init__(self):
super(Cpu, self).__init__()
self.type = "TR 2990WX"
self.price = 13599
class Gpu():
def __init__(self):
self.type = ""
self.price = 0
def do_some_function(self):
print('gpu用来渲染图形')
def __repr__(self):
return 'gpu'
class MsiGpu(Gpu):
def __init__(self):
super(Gpu, self).__init__()
self.type = "微星2070"
self.price = 3000
class Fan():
def __init__(self):
self.type = ""
self.price = 0
def do_some_function(self):
print('风扇用来散热')
def __repr__(self):
return 'fan'
class ScytheFan(Fan):
def __init__(self):
super(Fan, self).__init__()
self.type = "大镰刀"
self.price = 600
class ComputerBuilder():
def __init__(self) -> None:
self.reset()
def reset(self) -> None:
self._product = Computer()
@property
def product(self):
"""
调用产品的响应方法
:return:
"""
product = self._product
return product
def produce_cpu(self, cpu: Cpu) -> None:
self._product.add(cpu)
def produce_gpu(self, gpu: Gpu) -> None:
self._product.add(gpu)
def produce_fan(self, fan: Fan) -> None:
self._product.add(fan)
class Computer():
"""
定义好具体的产品,写上具体能实现的方法,比如该电脑类可以列出配置的具体型号
"""
def __init__(self) -> None:
self.parts = []
def add(self, part: Any) -> None:
self.parts.append(part)
def list_parts_type(self) -> None:
parts_type = '\n'.join([repr(part) + ':' + part.type for part in self.parts])
print('电脑配置如下:\n{}'.format(parts_type))
def total_parts_price(self):
total_price = sum([part.price for part in self.parts])
print('电脑总价:{}'.format(total_price))
return total_price
class Director:
"""
负责以特定的顺序来执行建造步骤
该类是可选的
"""
def __init__(self) -> None:
self._builder = None
@property
def builder(self) -> ComputerBuilder:
return self._builder
@builder.setter
def builder(self, builder: ComputerBuilder) -> None:
"""
使builder属性可赋值
"""
self._builder = builder
def build_minimal_computer(self) -> None:
self.builder.produce_cpu(InterCpu())
def build_full_computer(self) -> None:
self.builder.produce_cpu(InterCpu())
self.builder.produce_gpu(MsiGpu())
self.builder.produce_fan(ScytheFan())
if __name__ == '__main__':
director = Director()
computer_builder = ComputerBuilder()
director.builder = computer_builder
print('配置功能齐全的电脑')
director.build_full_computer()
computer_builder.product.total_parts_price()
computer_builder.product.list_parts_type()
print('-' * 20)
# 先将创建者重置
computer_builder.reset()
print('配置简陋的电脑')
director.build_minimal_computer()
computer_builder.product.total_parts_price()
computer_builder.product.list_parts_type()
print('-' * 20)
# 自定义装机
computer_builder.reset()
print('自定义装机')
computer_builder.produce_cpu(AMDCpu())
computer_builder.produce_fan(ScytheFan())
computer_builder.produce_gpu(MsiGpu())
computer_builder.product.total_parts_price()
computer_builder.product.list_parts_type()
得到如下结果: