创建型模式之建造者模式

举报
子都爱学习 发表于 2022/02/27 10:39:44 2022/02/27
【摘要】 建造者模式将一个复杂对象的构造与其表现形式进行分离,使得同样的构造过程能创建出不同的表现形式。意图Builder:抽象建造者(Builder)(引入抽象建造者的目的,是为了将建造的具体过程交与它的子类来实现。这样更容易扩展。一般至少会有两个抽象方法,一个用来建造产品,一个是用来返回产品。)ConcreteBuilder:具体建造者(CommonBuilder、SuperBuilder)(实现...

建造者模式

将一个复杂对象的构造与其表现形式进行分离,使得同样的构造过程能创建出不同的表现形式。

意图

  • Builder:抽象建造者(Builder)(引入抽象建造者的目的,是为了将建造的具体过程交与它的子类来实现。这样更容易扩展。一般至少会有两个抽象方法,一个用来建造产品,一个是用来返回产品。)

  • ConcreteBuilder:具体建造者(CommonBuilder、SuperBuilder)(实现抽象类的所有未实现的方法,具体来说一般是两项任务:组建产品;返回组建好的产品。)

  • Director:指挥者(Director)(负责调用适当的建造者来组建产品,指挥者类一般不与产品类发生依赖关系,与指挥者类直接交互的是建造者类。一般来说,指挥者类被用来封装程序中易变的部分。)

  • Product:产品角色(Role)

                           

优点

1、由于单例模式要求在全局内只有一个实例,因而可以节省比较多的内存空间; 2、全局只有一个接入点,可以更好地进行数据同步控制,避免多重占用; 3、单例可长驻内存,减少系统开销。


实现

1.抽象建造者


import time
STEP_DELAY = 0.1
PIZZA_PROGRESS = ['prepare', 'bake', 'cut', 'box']
# 抽象建造者
class PizzaBuilder(object):

    name = None

    def __init__(self):
        self.progress = PIZZA_PROGRESS
        self.baking_time = 5

    def prepare_dough(self):
        raise NotImplementedError()

    def add_sauce(self):
        raise NotImplementedError()

    def add_topping(self):
        raise NotImplementedError()

    def bake(self):
        raise NotImplementedError()

    def cut(self):
        raise NotImplementedError()

    def box(self):
        raise NotImplementedError()

    @property
    def pizza(self):
        return Pizza(self.name)


2.具体建造者


# 具体建造者
class NYStyleCheeseBuilder(PizzaBuilder):

    name = 'NY Style Sauce and Cheese Pizza'

    def prepare_dough(self):
        self.progress = PIZZA_PROGRESS[0]
        self.pizza.prepare_dough('thin')

    def add_sauce(self):
        print('adding the tomato sauce to your pizza..')
        self.pizza.sauce = 'tomato'
        time.sleep(STEP_DELAY)
        print('done with the tomato sauce')

    def add_topping(self):
        print('adding the topping (grated reggiano cheese) to your pizza')
        self.pizza.toppings.append(["Grated", "Reggiano", "Cheese"])
        time.sleep(STEP_DELAY)
        print('done with the topping (grated reggiano cheese)')

    def bake(self):
        self.progress = PIZZA_PROGRESS[1]
        print('baking your pizza for {} seconds'.format(self.baking_time))
        time.sleep(self.baking_time)

    def cut(self):
        self.progress = PIZZA_PROGRESS[2]
        print("Cutting the pizza into diagonal slices")

    def box(self):
        self.progress = PIZZA_PROGRESS[3]
        print("Place pizza in official PizzaStore box")

3.指挥者

# 指挥者
class Waiter:
    # 指挥者
    def __init__(self):
        self.builder = None

    def construct_pizza(self, builder):
        self.builder = builder
        #  一旦我们有了一个 pizza,需要做一些准备(擀面皮、加佐料),然后烘烤、切片、装盒
        [step() for step in (builder.prepare_dough, builder.add_sauce,
                             builder.add_topping, builder.bake,
                             builder.cut, builder.box)]
    @property
    def pizza(self):
        return self.builder.pizza

4.产品

# 产品
class Pizza:

    def __init__(self, name):
        self.name = name
        self.dough = None
        self.sauce = None
        self.toppings = []

    def prepare_dough(self, dough):
        self.dough = dough
        print(self.dough)
        print('preparing the {} dough of your {}...'.format(self.dough, self))
        time.sleep(STEP_DELAY)
        print('Done with the {} dough'.format(self.dough))

    def __str__(self):
        return self.name

流利的建造者

通过将建造者本身定义为内部类并从其每个设置器方法返回自身来实现。方法build()返回最终的对象。

# coding: utf-8
 
 
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)


缺点

1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。

应用

建造者模式和工厂方法模式最大的区别是,建造者模式多了一个指挥者的角色。建造者负责创建复杂对象的各个组成部分。而指挥者使用一个建造者实例控制建造的过程。与工厂模式相比,建造者模式一般用来创建更为复杂的对象,因为对象的创建过程更为复杂,因此将对象的创建过程独立出来组成一个新的类——指挥者类。

在以下几种情况下,与工厂模式相比,建造者模式是更好的选择。

  • 想要创建一个复杂对象(对象由多个部分构成,且对象的创建要经过多个不同的步骤,这些步骤也许还需遵从特定的顺序)
  • 要求一个对象能有不同的表现,并希望将对象的构造与表现解耦
  • 想要在某个时间点创建对象,但在稍后的时间点再访问
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。