The builder pattern separates the construction of a complex object from its performance, so that the same construction process can be used to create several different manifestations.
Let's look at a practical example, assuming that we want to create a HMTL page builder, the basic structure of the HTML page (the construction component) is usually the same: start
HTML page generation problems can be solved using builder mode. In this model, there are two participants: the builder and the conductor (director). Builders are responsible for creating the various components of complex objects. In the HTML example, these components are the page title, text title, content body, and footer. The conductor uses a builder instance to control the construction process. For the HTML example, this refers to the call Builder's function Settings page title, text caption, and so on. Using different builder instances allows us to create different HTML pages without having to change the code of the conductors.
Case
Let's take a look at how to use the builder design pattern to implement a pizza ordering application. The pizza example is particularly interesting because it takes a lot of steps to get a pizza ready, and these operations follow a specific order. To add seasonings, you have to prepare the dough first. To add ingredients, you need to add seasonings first. The pizza can only be baked when the seasoning and ingredients have been placed on the dough. In addition, each pizza usually requires a different baking time, depending on the thickness of the dough and the ingredients used.
The complete sample code (builder.py) is as follows:
#!/usr/bin/env python#-*-coding:utf-8-*-# @Date: 2018/7/15 9:59# @Author: Yaheng Wang ([email protected]) # @Link: http://www.wy2160640.github.io# @Version: 1.0from enum import Enumimport timepizzaprogress = enum (' Pizzaprogre SS ', ' Queued preparation baking ready ') Pizzadough = enum (' Pizzadough ', ' thin thick ') Pizzasauce = enum (' Pizzasauce ', ' Toma To Creme_fraiche ') pizzatopping = Enum (' pizzatopping ', ' mozzarella double_mozzarella bacon ham mushrooms red_onion Oregano ') Step_delay = 3class pizza:def __init__ (self, name): Self.name = name Self.dough = None S Elf.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__ (SE LF): 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): Prin T (' 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-I in (Pizzatopping.double_mozzarella, pizzatopping. Oregano)]) time.sleep (step_delay) print (' Done with the topping (double mozzarella, oregano) ') def bake (SE LF): self.progress = pizzaprogress.baking print (' Baking your margarita for {} seconds '. Format (self.baking_ti Me) 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 sel F.baking_time = 7 def prepare_dough (self): self.progress = pizzaprogress.preparation self.pizza.prepare_d Ough (Pizzadough.thick) def add_sauce (self): print (' adding, creme fraiche sauce to your creamy bacon ') Self.pizza.sauce = Pizzasauce.creme_fraiche 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 Yo ur 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 (' d One with the topping (mozzarella, bacon, ham, mushroom, red onion, oregano) "Def bake (self): self.progress = Pi Zzaprogress.baking Print (' Baking your creamy bacon for {} seconds '. Format (self.baking_time)) time.sleep (self.baking_time) sel F.progress = pizzaprogress.ready print (' Your creamy bacon is ready ') class Waiter:def __init__ (self): sel F.builder = None def construct_pizza (self, builder): Self.builder = Builder [Step () to step in (builder. Prepare_dough, Builder.add_sauce, builder.add_topping, Builder.bake)] @property def pizza (self): return to self. Builder.pizzadef Validate_style (Builders): Try:pizza_style = input (' What pizza would do 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) is available ') return (False, None) return (True, builder) def main (): Buil DERs = 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.P Izza print () print (' Enjoy your {}! '). Format (pizza)) if __name__ = = ' __main__ ': Main ()
Summary
In the following cases, the builder mode is a better choice than the factory model.
1. You want to create a complex object (the object is made up of multiple parts, and the object is created in several different steps and may need to follow a specific order)
2. Requires an object to behave differently, and wants to decouple the object's construction from its performance
3. Want to create an object at a point in time, but revisit it at a later point in time
(Turn from proficient in Python design mode) the creation mode of Python design mode--2. Builder mode