专栏首页喵叔's 专栏第三天:创建型模式--建造者模式

第三天:创建型模式--建造者模式

零、建造者模式

  • 什么是建造者模式 使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于建造者模式,它提供了一种创建对象的最佳方式,将一个复杂对象的构造过程与其表象分离,同一个构造过程可用于创建多个不同的表现。

一、身边的例子

  • 麦当劳 麦当劳的汉堡套餐种类有很多(如:汉堡+可乐、汉堡+薯条、汉堡+可乐+薯条),顾客在购买的时候关注的是套餐的种类(表现),而不关注套餐制作的过程(建造过程)。在这里顾客就是客户端,收银员就是指挥者,后厨人员就是建造者。
  • django-widgy django-widgy是Django的第三方编辑器扩展,可以构建不同风格的HTML代码。

二、什么情况下使用

创建一个由多个部分构成的对象,而且它的构成需要一步接一步地完成,只有当各个部分都创建好后,这个对象才算创建完成。

三、应用案例

以下代码,通过订购两种不同口味的比萨并,来进一步学习建造者模式

import time
from enum import Enum

PizzaProgress = Enum('PizzaProgress', 'queued preparation baking ready')
PizzaDough = Enum('PizzaDough', 'thin thick')
PizzaSauce = Enum('PizzaSauce', 'tomato creme_fraiche')
PizzaTopping = Enum('PizzaTopping', 'mozzarella double_mozzarella bacon ham mushrooms red_onion oregano')
STEP_DELAY = 3


class Pizza:
    '''
    最终产品类
    '''

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

    def __str__(self):
        return self.name

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


class CreamyBaconBuilder:
    """
    奶油熏肉比萨建造者
    """

    def __init__(self):
        self.pizza = Pizza('creamy bacon')
        self.progress = PizzaProgress.queued
        # 烤制时间
        self.baking_time = 7

    # 生面团
    def prepare_dough(self):
        self.progress = PizzaProgress.preparation
        self.pizza.prepare_dough(PizzaDough.thin)

    # 添加沙司
    def add_sauce(self):
        print('adding the creme fraiche sauce to your creamy bacon')
        self.pizza.sauce = PizzaSauce.Creme_fraiche
        # 暂停3秒,模拟制作的时间
        time.sleep(STEP_DELAY)
        print('done with the creme fraiche sauce')

    # 添加各种配料
    def add_topping(self):
        print('adding the topping (mozzarella,bacon,ham,mushrooms,red onion,oregano) to your creamy bacon')
        self.pizza.topping.append([t for t in (
            PizzaTopping.mozzarella, PizzaTopping.bacon, PizzaTopping.ham, PizzaTopping.mushrooms,
            PizzaTopping.red_onion, PizzaTopping.oregano)])
        time.sleep(STEP_DELAY)
        print('done with the topping (mozzarella,bacon,ham,mushrooms,red onion, oregano)')

    # 烤比萨
    def bake(self):
        self.progress = PizzaProgress.baking
        print('baking your creamy bacon for {} seconds'.format(self.baking_time))
        time.sleep(self.baking_time)
        self.progress = PizzaProgress.ready
        print('your creamy bacon is ready')


class MargaritaBuilder:
    '''
    玛格丽特比萨建造者
    '''

    def __init__(self):
        self.pizza = Pizza('margarita')
        self.progress = PizzaProgress.queued
        self.baking_time = 5

    def prepare_dough(self):
        self.progress = PizzaProgress.preparation
        self.pizza.prepare_dough(PizzaDough.thin)

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

    def add_topping(self):
        print('adding the topping (double mozzarella, oregano) to your margarita')
        self.pizza.topping.append([i for i in (PizzaTopping.double_mozzarella, PizzaTopping.oregano)])
        time.sleep(STEP_DELAY)
        print('done with the topping (double mozzarrella,oregano)')

    def bake(self):
        self.progress = PizzaProgress.baking
        print('baking your margarita for {} seconds'.format(self.baking_time))
        time.sleep(self.baking_time)
        self.progress = PizzaProgress.ready
        print('your margarita is ready')


class Waiter:
    '''
    服务员(指挥者)
    '''

    def __init__(self):
        self.builder = None

    def construct_pizza(self, builder):
        self.builder = builder
        [step() for step in (builder.prepare_dough, builder.add_sauce, builder.add_topping, builder.bake)]

    @property
    def pizza(self):
        return self.builder.pizza


def validate_style(builders):
    '''
    验证输入类
    '''
    try:
        pizza_style = input('What pizza would you like ,[m]argarita or [c]reamy bacon?')
        builder = builders[pizza_style]()
        vaild_input = True
    except KeyError as err:
        print('Sorry,only margarita (key m) and creamy bacon (key c) are availabke')
        return (False, None)
    return (True, builder)


def main():
    builders = dict(m=MargaritaBuilder, c=CreamyBaconBuilder)
    valid_input = False
    while not valid_input:
        valid_input, builder = validate_style(builders)
    waiter = Waiter()
    waiter.construct_pizza(builder)
    pizza = waiter.pizza
    print('Enjoy your  {}!'.format(pizza))


if __name__ == '__main__':
    main()

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 第四天:创建型模式--原型模式

    喵叔
  • 第二天:创建型模式--抽象工厂模式

    一开始使用工厂方法,在后期需要许多工厂方法,将创建一系列对象的过程合并在一起形成抽象工厂。抽象工厂有一个优点,在使用工厂方法是从用户视角通常是看不到的,抽象工厂...

    喵叔
  • 第四章--第二节:类

    在上面的代码中方法 init 是一个特殊的方法,在创建类的实例的时候,实例会自动调用这个方法,一般用来对实例的属性进行初使化。另类里面的两个方法都有 self ...

    喵叔
  • PyQt 5信号与槽的几种高级玩法

    在Qt中,每一个QObject对象和PyQt中所有继承自QWidget的控件(这些都是QObject的子对象)都支持信号与槽机制。当信号发射时,连接的槽函数将会...

    博文视点Broadview
  • 11 Python 基础: 知识巩固,实现一个简易学生管理系统

    首先,我们定义了一个LoginModule类,此为登录模块,主要功能就是定义账号属性【用户名,密码】,然后定义一个登录login方法实现验证用户名和密码是否正确...

    小Gy
  • python pyqt5 QCalendar

    setDateRange() setMinimumDate() setMaxmumDate() setSelectedDate()

    用户5760343
  • python pyqt5 QToolBar

    import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.Qt...

    用户5760343
  • PyQt5 截取屏幕

    用户6021899
  • 6.wxPython防止窗体重画棋子消失的机制

    可以画图的类中wx.ClientDC不必依赖窗体绘画事件,可以随时实例化,随时画图。但是窗体最小化之后再恢复,重画的窗体上通过wx.ClientDC绘制的棋子会...

    用户4381798
  • 手把手教你用Python开发“剪刀石头布”小游戏【附源码】

    最近在学习PyQt5可视化界面,这是一个内容非常丰富的gui库,相对于tkinter库,功能更加强大,界面更加美观,操作也不难。于是我开始小试牛刀,用PyQt...

    python学习教程

扫码关注云+社区

领取腾讯云代金券