设计模式二:建造者模式
建造者模式
想要创建一个由多个部分构成的对象,而且他的构成需要一步接一步地完成。只有当各个部分都创建好,这个对象才是完整的。这时就需要建造者模式
建造者设计模式:将一个复杂对象的构造过程与其表现分离,构造过程可用于创建多个不同的表现。
该模式中有两个参与者:建造者和指挥者
建造者负责创建复杂对象的各个组成部分。
指挥者使用建造者实例控制建造的过程。
建造者模式与工厂模式的区别
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)
使用命名参数
使用实参列表展开
工厂模式和建造者模式的区别
- 工厂模式以单个步骤创建对象,创建者模式以多个步骤创建对象,并且几乎始终会使用一个指挥者。
- 在工厂模式下,会立即返回一个创建好的对象;而在建造者模式下,仅在需要时客户端代码才显示地请求指挥者返回最终的对象
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的要求,有不同的烘焙时间,依赖于生面团的厚度和使用的配料
应用中有两个建造者:
- 制作玛格丽特披萨(MargaritaBuilder)
- 制作奶油熏肉披萨(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
设计模式二:建造者模式相关推荐
- 建造者模式java_java设计模式3——建造者模式
java设计模式3--建造者模式 1.建造者模式介绍: 建造者模式属于创建型模式,他提供了一种创建对象得最佳方式 定义: 将一个复杂对象的构建和与它的表示分离,使得同样的构建过程可以创建不同的表示 主 ...
- Java设计模式(建造者模式-适配器模式-桥接模式)
Java设计模式Ⅲ 1.建造者模式 1.1 建造者模式概述 1.2 建造者模式的注意事项和细节 1.3 代码理解 2.适配器模式 2.1 类适配器模式 2.1.1 代码理解 2.2 对象适配器模式 2 ...
- C#设计模式之四建造者模式(Builder Pattern)【创建型】
一.引言 今天我们要讲讲Builder模式,也就是建造者模式,当然也有叫生成器模式的,英文名称是Builder Pattern.在现实生活中,我们经常会遇到一些构成比较复杂的物品,比如:电脑,它就是一 ...
- 学习《图说设计模式》建造者模式
图说设计模式之建造者模式 1. 模式动机 无论是在现实世界中还是在软件系统中,都存在一些复杂的对象,它们拥有多个组成部分,如汽车,它包括车轮.方向盘.发送机等各种部件.而对于大多数用户而言,无须知道这 ...
- java设计模式之建造者模式(UML类图分析+代码详解)
大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...
- D5:C#设计模式之四建造者模式(Builder Pattern)【创建型】
一.引言 今天我们要讲讲Builder模式,也就是建造者模式,当然也有叫生成器模式的,英文名称是Builder Pattern.在现实生活中,我们经常会遇到一些构成比较复杂的物品,比如:电脑,它就是一 ...
- 折腾Java设计模式之建造者模式
博文原址:折腾Java设计模式之建造者模式 建造者模式 Separate the construction of a complex object from its representation, a ...
- java设计模式 建造模式_理解java设计模式之建造者模式
理解java设计模式之建造者模式 发布于 2020-12-10| 复制链接 摘记: 建造者模式(Builder Pattern)主要用于"分步骤构建一个复杂的对象",在这其中&qu ...
- 建造者模式 php,PHP设计模式之建造者模式定义与用法简单示例
本文实例讲述了PHP设计模式之建造者模式.分享给大家供大家参考,具体如下: 建造者模式: 将复杂对象的创建过程和表示进行分离(好吧,我也看不懂什么意思1). 来点我人类能听懂的话: 1.在客户端看来需 ...
- 实践GoF的23种设计模式:建造者模式
本文分享自华为云社区<[Go实现]实践GoF的23种设计模式:建造者模式>,作者: 元闰子. 简述 在程序设计中,我们会经常遇到一些复杂的对象,其中有很多成员属性,甚至嵌套着多个复杂的对象 ...
最新文章
- HTTP头信息中的参数Etag
- 零基础学习UI设计有哪些简单有效的方法
- Alibaba 之 Nacos
- luogu P3234 [HNOI2014]抄卡组
- 男人是房子,女人是车子
- C# 5.0 CallerMemberName CallerFilePath CallerLineNumber获取调用方法名称,路径,行号
- 产品设计体会(1015)用户访谈的常见问题与对策
- 英知汇——名词、动词、形容词、副词的形容词,绕不绕?
- C语言自定义函数使用
- Python编程之找完数
- 【C++】 文件提取英文单词
- 一个男朋友写给女朋友的信!爆笑(真勇敢)
- ZXing实现横竖屏扫描切换
- [开心学php100天]第六天:用php玩转页面(基础篇)
- 我的世界java地狱更新_【我的世界】我得世界:1.16地狱大年夜更新_玩得好游戏攻略...
- Mac上如何用自带软件剪切音频(去除多余杂音)?
- android友盟自定义事件,友盟统计事件添加
- 服务器显示htx插槽,Socket F接口Opteron主板与服务器Computex展示
- 浅议网上支付系统关键技术探究
- Android定时相关