设计模式- 创建型模式, 建造者模式(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)
反对极端面向过程编程思维方式,喜欢面向对象和设计模式的解读,喜欢对比极端面向过程编程和oop编程消耗代码代码行数的区别和原因。致力于使用oop和36种设计模式写出最高可复用的框架级代码和使用最少的代码行数完成任务,致力于使用oop和设计模式来使部分代码减少90%行,使绝大部分py文件最低减少50%-80%行的写法。