python设计模式之生成器模式

生成器模式是一种创建型设计模式, 使你能够分步骤创建复杂对象,生成器不允许其他对象访问正在创建中的产品。 该模式允许你使用相同的创建代码生成不同类型和形式的对象。又名建造者模式。

为什么需要?

简化复杂的构造函数。只有当产品较为复杂且需要详细配置时,使用生成器模式才有意义。生成器与其他创建型模式的不同之处在于:它让你能创建不遵循相同接口的产品。

应用场景

  • 使用生成器模式可避免 “重叠构造函数 (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()

得到如下结果:
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值