zoukankan      html  css  js  c++  java
  • 设计模式- 创建型模式, 建造者模式(2)

    java23种设计模式之一,英文叫Builder Pattern。其核心思想是将一个“复杂对象的构建算法”与它的“部件及组装方式”分离,使得构件算法和组装方式可以独立应对变化;复用同样的构建算法可以创建不同的表示,不同的构建过程可以复用相同的部件组装方式。

    # coding: utf-8
    
    from enum import Enum
    import time
    
    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 your {}...'.format(self.dough.name, self))
            time.sleep(STEP_DELAY)
            print('done with the {} dough'.format(self.dough.name))
    
    
    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 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.thick)
    
        def add_sauce(self):
            print('adding the crème fraîche sauce to your creamy bacon')
            self.pizza.sauce = PizzaSauce.creme_fraiche
            time.sleep(STEP_DELAY)
            print('done with the crème fraîche 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 Waiter:
    
        def __init__(self):
            self.builder = None      ## 实例属性最好写在__init__里面,哪怕属性不是在初始化时候绑定或者建立,也有写个None,声明一下属性,否则直接在普通方法生成一个实例属性,不符合pycharm的pep8。
    
        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]()
            valid_input = True
        except KeyError as err:
            print('Sorry, only margarita (key m) and creamy bacon (key c) are available')
            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)
        print()
        waiter = Waiter()
        waiter.construct_pizza(builder)
        pizza = waiter.pizza
        print()
        print('Enjoy your {}!'.format(pizza))
    
    if __name__ == '__main__':
        main()

    看代码先从main函数看起,不是从上往下一行行看,通过。

     waiter在其他例子中通常也会叫director。例如下面。一个产品类,通过把不同的构建者传给导演类创造不同属性的产品对象。

    class Director(object):
        def __init__(self):
            self.builder = None
     
        def construct_building(self):
            self.builder.new_building()
            self.builder.build_floor()
            self.builder.build_size()
     
        def get_building(self):
            return self.builder.building
     
     
    # Abstract Builder
    class Builder(object):
        def __init__(self):
            self.building = None
     
        def new_building(self):
            self.building = Building()
     
     
    # Concrete Builder
    class BuilderHouse(Builder):
        def build_floor(self):
            self.building.floor = 'One'
     
        def build_size(self):
            self.building.size = 'Big'
     
     
    class BuilderFlat(Builder):
        def build_floor(self):
            self.building.floor = 'More than One'
     
        def build_size(self):
            self.building.size = 'Small'
     
     
    # Product
    class Building(object):
        def __init__(self):
            self.floor = None
            self.size = None
     
        def __repr__(self):
            return 'Floor: %s | Size: %s' % (self.floor, self.size)
     
     
    # Client
    if __name__ == "__main__":
        director = Director()
        director.builder = BuilderHouse()
        director.construct_building()
        building = director.get_building()
        print(building)
        director.builder = BuilderFlat()
        director.construct_building()
        building = director.get_building()
        print(building)
  • 相关阅读:
    互联网协议入门
    C++解决约瑟夫环(史上最清晰)
    C# 最快的逐一打印斐波那契结果数列的算法
    二叉树的遍历(转载)
    C# 多线程join的用法,等待多个子线程结束后再执行主线程
    剖丁解牛式的快速排序分析
    用CTE结合排名函数rank()删除某列值重复的记录
    Http 头部属性详解
    C# 冒泡排序
    设计模式七大原则之依赖倒转原则
  • 原文地址:https://www.cnblogs.com/ydf0509/p/8525561.html
Copyright © 2011-2022 走看看