首页
学习
活动
专区
圈层
工具
发布

Python 设计模式(4):生成器模式

生成器模式与工厂方法模式有着相似之处,两者都属于创建型模式,并且都是将对象创建的任务交给一个单独的类去完成。

生成器模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创造不同的表示。生成器模式的设计类图如图所示。

生成器模式按照一个指定的过程逐步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以创建它们,而不必知道内部的具体构建细节。生成器模式的主要思想是抽象出创建对象的步骤,使得这些步骤的不同实现可以创建对象的不同表示。通常,生成器模式被用来创建符合组合模式的产品对象。

生成器模式所包含的各组成部分意义如下。

  1. Builder:创建 Product 对象的抽象接口。
  2. ConcreteBuilder:(1)通过对抽象的 Builder 接口的具体实现,创建并组装创建这些对象的“零件”。(2)定义并且跟踪它所创建的产品的表示。(3)提供一个接口以便能被调用,得到产品对象。
  3. Director:使用 Builder 接口创建一个完整的产品对象,它负责管理正确的对象创建顺序,从参数中接受具体的 ConcreteBuilder 对象,并且执行这些对象的必要的操作。
  4. Product:(1)代表待创建的复杂对象,是 ConcreteBuilder 负责创建对象的内部表示,并且定义组装过程。(2)包含产品定义组件的子类,包括一个组装接口。值得注意的是,产品类可以是一个单独(属性比较复杂)的类,也可以是一个带有子类的类结构体。在是单独类的情况下,ConcreteBuilder 负责创建该单独类对象的内部表示;在是一个类结构体的情况下,ConcreteBuilder 根据需要创建该所需要的子类的内部表示,然后再组装在一起。

使用生成器模式的特点如下。

  1. 生成器让用户可以变化它建造产品的内部表达形式,它也隐藏了产品怎样被装配的细节。
  2. 每个具体的生成器都独立与程序的其他生成器,因此改善了程序的模块化,并且使添加其他生成器变得相对简单。
  3. 由于每个生成器根据数据逐步构建最终产品,用户对生成器构建的最终产品有更多的控制。
  4. 生成器模式与抽象工厂模式有相似之处,都返回一些由其他对象组成的类的对象。主要区别是,抽象工厂模式返回一个类族,而生成器模式逐步按照次序构建一个复杂的对象,最后该对象被返回。
代码语言:javascript
复制
from abc import ABC, abstractmethod


class Product:
    def __init__(self):
        self.type = self.a = self.b = None

    def __str__(self):
        return f"Product{self.type},a:{self.a},b:{self.b}"


class Builder(ABC):
    def __init__(self):
        self.product = Product()

    @abstractmethod
    def create_component_a(self):
        pass

    @abstractmethod
    def create_component_b(self):
        pass

    def get_object(self):
        return self.product


class ConcreteBuilder1(Builder):
    def __init__(self):
        super().__init__()
        self.product.type = "1"

    def create_component_a(self):
        self.product.a = "1"

    def create_component_b(self):
        self.product.b = "1"


class ConcreteBuilder2(Builder):
    def __init__(self):
        super().__init__()
        self.product.type = "2"

    def create_component_a(self):
        self.product.a = "2"

    def create_component_b(self):
        self.product.b = "2"


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

    def set_builder(self, builder):
        self.builder = builder

    def construct(self):
        self.builder.create_component_a()
        self.builder.create_component_b()


class Client:
    @staticmethod
    def main():
        director = Director()
        concrete_builder = ConcreteBuilder1()
        director.set_builder(concrete_builder)
        director.construct()
        print(concrete_builder.get_object())
        concrete_builder = ConcreteBuilder2()
        director.set_builder(concrete_builder)
        director.construct()
        print(concrete_builder.get_object())


if __name__ == '__main__':
    Client.main()
举报
领券