建造者模式

想要创建一个由多个部分构成的对象,而且他的构成需要一步接一步地完成。只有当各个部分都创建好,这个对象才是完整的。这时就需要建造者模式

建造者设计模式:将一个复杂对象的构造过程与其表现分离,构造过程可用于创建多个不同的表现。

该模式中有两个参与者:建造者指挥者

建造者负责创建复杂对象的各个组成部分。

指挥者使用建造者实例控制建造的过程。

建造者模式与工厂模式的区别

1.工厂模式以单个步骤创建对象,而建造者模式以多个步骤创建独享,并且几乎始终使用同一个指挥者;

2.在工厂模式下,会立即返回一个创建好的对象;而在建造者模式下,仅在需要时客户端代码才显示地请求指挥者返回最终的对象。

其实在django-widgy中建造者模式就得到了实际应用。django-widgy是一个Django的第三方树编辑器扩展,可用作内容管理系统(Content Management System, CMS)。它包含一个网页构建器,用在创建不同布局的HTML页面。

1. 建造者模式的苹果电脑应用案例

类里面套一个类,这种写法可以禁止直接实例化一个类的简洁方式

一个苹果电脑的例子,制造商将所有的硬件规格都隐藏了起来,客户只知道去买某个品牌和型号的笔记本

可以看到只有AppleFactory类实例化, 但生产的其他参数都隐藏了起来,无法直接实例化生产过程MacMini14
过程的参数,让购买者无需关心内部生产的过程

MINI14 = '1.4GHZ Mac mini'class AppleFactory:class MacMini14:def __init__(self):self.memory = 4 # 单位为GBself.hdd = 500 # 单位为GBself.gpu = 'Intel HD Graphics 5000'def __str__(self):info = ('Model: {}'.format(MINI14),'Memory: {}GB'.format(self.memory),'Hard Disk: {}GB'.format(self.hdd),'Graphics Card: {}'.format(self.gpu))return '\n'.join(info)def build_computer(self, model):if (model == MINI14):return self.MacMini14()else:print("I don't know how to build {}".format(model))if __name__ == '__main__':afac = AppleFactory()mac_mini = afac.build_computer(MINI14)print(mac_mini)

使用命名参数

使用实参列表展开

工厂模式和建造者模式的区别

  1. 工厂模式以单个步骤创建对象,创建者模式以多个步骤创建对象,并且几乎始终会使用一个指挥者。
  2. 在工厂模式下,会立即返回一个创建好的对象;而在建造者模式下,仅在需要时客户端代码才显示地请求指挥者返回最终的对象

2. 案例二:作为指挥者向制造商提供指令,制作想要的电脑

首先实例化HardwareEngineer,调用并传参construct_computer(self, memory, hdd, gpu),再去实例化ComputerBuilder()--> Computer()

列表式执行函数

        [step for step in (self.builder.configure_momory(memory),self.builder.configure_hdd(hdd),self.builder.configure_gpu(gpu))]
class Computer:def __init__(self, serial_number):self.serial = serial_numberself.memory = None  # 单位为GBself.hdd = None     # 单位为GBself.gpu = Nonedef __str__(self):info = ('Memory: {}GB'.format(self.memory),'Hard Disk: {}GB'.format(self.hdd),'Graphics Card: {}'.format(self.gpu))return '\n'.join(info)class ComputerBuilder:def __init__(self):self.computer = Computer('AG23385193')def configure_momory(self, amount):self.computer.memory = amountdef configure_hdd(self, amount):self.computer.hdd = amountdef configure_gpu(self, gpu_model):self.computer.gpu = gpu_modelclass HardwareEngineer:def __init__(self):self.builder = Nonedef construct_computer(self, memory, hdd, gpu):self.builder = ComputerBuilder()[step for step in (self.builder.configure_momory(memory),self.builder.configure_hdd(hdd),self.builder.configure_gpu(gpu))]@propertydef computer(self):return self.builder.computerdef main():engineer = HardwareEngineer()engineer.construct_computer(hdd=500, memory=8, gpu='GeForce GTX 650 Ti')computer = engineer.computerprint(computer)if __name__ == '__main__':'''通过HardwareEngineer(传参调用ComputerBuilder,可以使用其他类也可以) --> ComputerBuilder --> Computer(负责打印输出数据)'''main()

可以看出,类实例化是一层一层的进行的,但是得指挥者main()却只是执行时进行了一次实例化

3. 使用建造者(builder)模式制作Pizza

制作披萨需要特定的顺序,才能制作:

先要准备:配料、调味料、生面团

然后,生面团上面撒上调味料和配料

根据不同的pizza的要求,有不同的烘焙时间,依赖于生面团的厚度和使用的配料

应用中有两个建造者:

  1. 制作玛格丽特披萨(MargaritaBuilder)
  2. 制作奶油熏肉披萨(CreamyBaconBuilder)

from enum import Enum
import timePizzaProgress = 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 = 3class Pizza:def __init__(self, name):self.name = nameself.dough = Noneself.sauce = Noneself.topping =[]def __str__(self):return self.namedef prepare_dough(self, dough):self.dough = doughprint('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.queuedself.baking_time = 5def prepare_dough(self):self.progress = PizzaProgress.preparationself.pizza.prepare_dough(PizzaDough.thin)def add_sauce(self):print('adding the tomato sauce to your margarita...')self.pizza.sauce = PizzaSauce.tomatotime.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.bakingprint('baking your margarita for {} seconds'.format(self.baking_time))time.sleep(self.baking_time)self.progress = PizzaProgress.readyprint('your margarita is ready')class CreamyBaconBuilder:def __init__(self):self.pizza = Pizza('creamy bacon')self.progress = PizzaProgress.queuedself.baking_time = 7def prepare_dough(self):self.progress = PizzaProgress.preparationself.pizza.prepare_dough(PizzaDough.thick)def add_sauce(self):print('adding the creme fraiche sauce to your creamy bacon')self.pizza.sauce = PizzaSauce.creme_fraichetime.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, mushroom, red onion, oregano)')def bake(self):self.progress = PizzaProgress.bakingprint('baking your creamy bacon for {} second'.format(self.baking_time))time.sleep((self.baking_time))self.progress = PizzaProgress.readyprint('your creamy bacon is ready')class Waiter:def __init__(self):self.builder = Nonedef construct_pizza(self, builder):self.builder = builder[step() for step in (builder.prepare_dough,builder.add_sauce, builder.add_topping, builder.bake)]@propertydef pizza(self):return self.builder.pizzadef validata_style(builders):try:pizza_style = input('What pizza would you like, [m]argarita or [c]reamy bacon? ')builder = builders[pizza_style]()valid_input = Trueexcept 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 = Falsewhile not valid_input:valid_input, builder = validata_style(builders)print()waiter = Waiter()waiter.construct_pizza(builder)pizza = waiter.pizzaprint()print('Enjoy your {}!'.format(pizza))if __name__ == '__main__':main()

4.链式调用建造者方法(流利的建造者):Pizza链式方法

Pizza类中包含PizzaBuilder()

build() 实例化Pizza(), 传入参数self,就是Pizza的形参builder

class Pizza:def __init__(self, builder):self.garlic = builder.garlicself.extra_cheese = builder.extra_cheesedef __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 = Falseself.garlic = Falsedef add_garlic(self):self.garlic = Truereturn selfdef add_extra_cheese(self):self.extra_cheese = Truereturn selfdef build(self):# 实例化Pizza(), 传入参数self,就是Pizza的形参builderreturn Pizza(self)if __name__ == '__main__':# Pizza类中包含PizzaBuilder()pizza = Pizza.PizzaBuilder().add_garlic().add_extra_cheese().build()print(pizza)# a = Pizza# print(a)# b = a.PizzaBuilder()# print(b)# c = b.add_garlic().add_extra_cheese().build()# print(c)

转载于:https://www.cnblogs.com/myt2000/p/11570037.html

设计模式二:建造者模式相关推荐

  1. 建造者模式java_java设计模式3——建造者模式

    java设计模式3--建造者模式 1.建造者模式介绍: 建造者模式属于创建型模式,他提供了一种创建对象得最佳方式 定义: 将一个复杂对象的构建和与它的表示分离,使得同样的构建过程可以创建不同的表示 主 ...

  2. Java设计模式(建造者模式-适配器模式-桥接模式)

    Java设计模式Ⅲ 1.建造者模式 1.1 建造者模式概述 1.2 建造者模式的注意事项和细节 1.3 代码理解 2.适配器模式 2.1 类适配器模式 2.1.1 代码理解 2.2 对象适配器模式 2 ...

  3. C#设计模式之四建造者模式(Builder Pattern)【创建型】

    一.引言 今天我们要讲讲Builder模式,也就是建造者模式,当然也有叫生成器模式的,英文名称是Builder Pattern.在现实生活中,我们经常会遇到一些构成比较复杂的物品,比如:电脑,它就是一 ...

  4. 学习《图说设计模式》建造者模式

    图说设计模式之建造者模式 1. 模式动机 无论是在现实世界中还是在软件系统中,都存在一些复杂的对象,它们拥有多个组成部分,如汽车,它包括车轮.方向盘.发送机等各种部件.而对于大多数用户而言,无须知道这 ...

  5. java设计模式之建造者模式(UML类图分析+代码详解)

    大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...

  6. D5:C#设计模式之四建造者模式(Builder Pattern)【创建型】

    一.引言 今天我们要讲讲Builder模式,也就是建造者模式,当然也有叫生成器模式的,英文名称是Builder Pattern.在现实生活中,我们经常会遇到一些构成比较复杂的物品,比如:电脑,它就是一 ...

  7. 折腾Java设计模式之建造者模式

    博文原址:折腾Java设计模式之建造者模式 建造者模式 Separate the construction of a complex object from its representation, a ...

  8. java设计模式 建造模式_理解java设计模式之建造者模式

    理解java设计模式之建造者模式 发布于 2020-12-10| 复制链接 摘记: 建造者模式(Builder Pattern)主要用于"分步骤构建一个复杂的对象",在这其中&qu ...

  9. 建造者模式 php,PHP设计模式之建造者模式定义与用法简单示例

    本文实例讲述了PHP设计模式之建造者模式.分享给大家供大家参考,具体如下: 建造者模式: 将复杂对象的创建过程和表示进行分离(好吧,我也看不懂什么意思1). 来点我人类能听懂的话: 1.在客户端看来需 ...

  10. 实践GoF的23种设计模式:建造者模式

    本文分享自华为云社区<[Go实现]实践GoF的23种设计模式:建造者模式>,作者: 元闰子. 简述 在程序设计中,我们会经常遇到一些复杂的对象,其中有很多成员属性,甚至嵌套着多个复杂的对象 ...

最新文章

  1. HTTP头信息中的参数Etag
  2. 零基础学习UI设计有哪些简单有效的方法
  3. Alibaba 之 Nacos
  4. luogu P3234 [HNOI2014]抄卡组
  5. 男人是房子,女人是车子
  6. C# 5.0 CallerMemberName CallerFilePath CallerLineNumber获取调用方法名称,路径,行号
  7. 产品设计体会(1015)用户访谈的常见问题与对策
  8. 英知汇——名词、动词、形容词、副词的形容词,绕不绕?
  9. C语言自定义函数使用
  10. Python编程之找完数
  11. 【C++】 文件提取英文单词
  12. 一个男朋友写给女朋友的信!爆笑(真勇敢)
  13. ZXing实现横竖屏扫描切换
  14. [开心学php100天]第六天:用php玩转页面(基础篇)
  15. 我的世界java地狱更新_【我的世界】我得世界:1.16地狱大年夜更新_玩得好游戏攻略...
  16. Mac上如何用自带软件剪切音频(去除多余杂音)?
  17. android友盟自定义事件,友盟统计事件添加
  18. 服务器显示htx插槽,Socket F接口Opteron主板与服务器Computex展示
  19. 浅议网上支付系统关键技术探究
  20. Android定时相关

热门文章

  1. 看了蛮久zhttty的《无限恐怖》才发现
  2. win10拨号上网不能开启移动热点 解决方案
  3. 周静:在不确定的世界里,做品高确信对客户有价值的事
  4. css---字体分类
  5. cad在图层设置中改不了线性和线宽
  6. dom元素属性操作---属性获取或属性设置
  7. vue中用highcharts制作韦恩图
  8. Macbook如何绕过公司网络限制
  9. 武术进学校 传递正能量
  10. 【话说私有云】企业需了解的私有云的10个真相 | 燕麦企业云盘(OATOS)