Python 设计模式之建造者模式 Builder Pattern
#引入建造者模式
肯德基的菜单上有 薯条, 鸡腿,鸡翅,鸡米花,可乐,橙汁,火腿汉堡,至尊虾汉堡,牛肉汉堡 , 鸡肉卷等这些单品,也有很多套餐。
比如
套餐1:鸡翅,至尊虾汉堡,可乐,薯条
套餐2:鸡腿,火腿汉堡,橙汁,薯条
套餐3: 。。。。。
全家桶:。。。。。
这种有各种各样的单品一步一步生成各种套餐, 这种过程称的上建造者模式
使用多个简单的对象一步一步构建成一个复杂的对象,有点像造房子一样一步步从地基做起到万丈高楼。我想这也是为什么被称呼为建造者模式的原因吧!
#建造者定义
Separate the construction of a complex object from its representation so that the same construction process can create different representations.
将一个复杂对象的构建与它的表示进行分离,使得同样的构建过程可以创建不同的表示。
这个定义里面的 ‘不同的表示’ 意思是不同的产品, 或者是不同的功能。
简单理解:建造者模式(Builder Pattern) 具备两层含义:
- 构建与表示分离:构建 代表对象创建,表示 代表对象行为/方法,也就是对象的创建与行为进行分离(对应到 java 代码,其实就是使用 接口 规定行为,然后由具体的实现类进行构建)。
- 创建不同的表示:也就是具备同样的行为,但是却由于构建的行为顺序不同或其他原因可以创建出不同的表示。
我们看完上述 建造者模式 的定义,就知道它与 工厂模式 是非常相似的。构建与表示分离 和 创建不同的表示 对于 工厂模式 同样具备。建造者模式 唯一区别于 工厂模式 主要是针对 复杂对象的构建。
也就是说,如果是创建简单对象,我们通常都是使用 工厂模式 进行创建;而如果是创建复杂对象,那么此时就可以考虑使用 建造者模式。
#主要解决
当需要构建的产品具备 复杂创建 过程时,可以抽取出共性构建过程,然后交由具体实现类自定义构建流程,使得同样的构建行为可以生产出不同的产品,分离了构建与表示,使构建产品灵活性大大增加。
#使用场景
看到上面的模式定义内容,可以根据内容剥离出这个模式的使用场景
1)需要生成的产品对象有复杂的内部结构,这些产品对象具备共性;
2)隔离复杂对象的创建和使用,并使得相同的构建过程可以创建不同的产品。
#建造者模式的优点
我在百度文库里看到了这个作者的文章,我喜欢ta的表述,不能复制,我就敲下来放这里了
1)在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建进行解耦,使得相同的创建过程可以创建不同的产品对象
2)每一个具体建造者都是独立的,与其他的具体建造者无关,,因此可以很方便的替换具体建造者或增加具体建造者,用户使用不同的具体建造者可得到不同的产品对象,由于指挥者类针对抽象建造者编程,增加新的具体建造者无需修改原有类库的代码,系统扩展方便,符合开闭原则。在编写代码中,代码复用率是尤为重要的
3)用户可以更为精细的控制产品的创建过程,将复杂的产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程
#建造者模式的缺点
1)建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性较大,例如很多组成部分不相同,则不适合使用建造者模式,因此使用范围受到一定的限制
2)如果产品的内部变化复杂,可能需要很多具体建造者类类实现这种变化,导致系统变得庞大,增加了系统的理解难度和运行成本
#建造者模式 主要包含四种角色:
1)抽象建造者(Builder):主要用于规范产品类的各个组成部分,并提供一个返回完整产品的接口。
2)具体建造者(Concrete Builder):实现 抽象建造者 规定的各个方法,返回一个组件好的具体产品。
3)产品(Product):构建相当复杂的类型,建造者最终创建的产品类型。
4)导演者(Director):指导 建造者(Builder) 以特定行为构建出产品,并将其返回给客户。
总结:理解了 建造者模式 的四种角色,其实就已经掌握了 建造者模式 的真谛:建造者模式 最终返回一个具体的构建复杂的产品;系统中产品可能只有一种类型或多种类型,但对某些产品族来说,它们具备相同的行为,因此对这些共性行为进行抽象,抽离出 抽象建造者(Builder);而对这些行为的具体构建过程,则交由 具体建造者(Concrete Builder) 负责,不同的 具体建造者 会构建出不同表示的产品;而具体要构建出哪种产品,由 导演者(Director) 决定。导演者 会选择不同的 具体建造者,指导它构建出产品。
#注意,也可以静态内部类实现 建造者模式
事实上,在平常的代码中,我们通常都会忽略对象的复杂性,使用 工厂模式 创建对象,而不是 建造者模式。正如上文所讲,工厂模式 和 建造者模式 的作用都是用于创建一个产品对象,而 工厂模式 结构更加简洁直接(没有 Builder 和 Director),因此更常使用。
而 建造者模式,我们更加习惯使用 静态内部类 的方式进行实现,即一个 产品类 内部自动带有一个 具体建造者(Concrete Builder),由它负责该产品的组装创建。不再需要 抽象建造者(Builder) 和 导演者(Director),这样,使得产品与构建之间的联系更加紧密,结构更加紧凑,同时使得 建造者模式 形式更加简洁。
#举个例子
这个订单系统的例子很容易理解,作者写的有点冗余,不过完全能说明这是一个建造者模式
class Burger():
"""
主食类,价格名字
"""
name=""
price=0.0
def getPrice(self):
return self.price
def setPrice(self,price):
self.price=price
def getName(self):
return self.name
class cheeseBurger(Burger):
"""
奶酪汉堡
"""
def __init__(self):
self.name="cheese burger"
self.price=10.0
class spicyChickenBurger(Burger):
"""
香辣鸡汉堡
"""
def __init__(self):
self.name="spicy chicken burger"
self.price=15.0 class Snack():
"""
小食类,价格以及名字
"""
name = ""
price = 0.0
type = "SNACK"
def getPrice(self):
return self.price
def setPrice(self, price):
self.price = price
def getName(self):
return self.name
class chips(Snack):
"""
炸薯条
"""
def __init__(self):
self.name = "chips"
self.price = 6.0
class chickenWings(Snack):
"""
鸡翅
"""
def __init__(self):
self.name = "chicken wings"
self.price = 12.0 class Beverage():
"""
饮料
"""
name = ""
price = 0.0
type = "BEVERAGE"
def getPrice(self):
return self.price
def setPrice(self, price):
self.price = price
def getName(self):
return self.name
class coke(Beverage):
"""
可乐
"""
def __init__(self):
self.name = "coke"
self.price = 4.0
class milk(Beverage):
"""
牛奶
"""
def __init__(self):
self.name = "milk"
self.price = 5.0 class order():
"""
订单对象,一个订单中包含一份主食,一份小食,一份饮料
"""
burger=""
snack=""
beverage=""
def __init__(self,orderBuilder):
self.burger=orderBuilder.bBurger
self.snack=orderBuilder.bSnack
self.beverage=orderBuilder.bBeverage
def show(self):
print("Burger:%s"%self.burger.getName())
print("Snack:%s"%self.snack.getName())
print("Beverage:%s"%self.beverage.getName()) # 建造者
class orderBuilder():
"""
orderBuilder就是建造者模式中所谓的“建造者”,
将订单的建造与表示相分离,以达到解耦的目的。
在上面订单的构建过程中,如果将order直接通过参数定义好(其构建与表示没有分离),
同时在多处进行订单生成,此时需要修改订单内容,
则需要一处处去修改,业务风险也就提高了不少。
"""
bBurger=""
bSnack=""
bBeverage=""
def addBurger(self,xBurger):
self.bBurger=xBurger
def addSnack(self,xSnack):
self.bSnack=xSnack
def addBeverage(self,xBeverage):
self.bBeverage=xBeverage
def build(self):
return order(self) # Director类
class orderDirector():
"""
在建造者模式中,还可以加一个Director类,用以安排已有模块的构造步骤。
对于在建造者中有比较严格的顺序要求时,该类会有比较大的用处。
"""
order_builder=""
def __init__(self,order_builder):
self.order_builder=order_builder
def createOrder(self,burger,snack,beverage):
self.order_builder.addBurger(burger)
self.order_builder.addSnack(snack)
self.order_builder.addBeverage(beverage)
return self.order_builder.build() #场景实现
if __name__=="__main__":
order_builder=orderBuilder()
order_builder.addBurger(spicyChickenBurger())
order_builder.addSnack(chips())
order_builder.addBeverage(milk())
order_1=order_builder.build()
order_1.show()
#参考
https://www.jianshu.com/p/47329a94f5dc
https://wenku.baidu.com/view/34a8a76cb9f67c1cfad6195f312b3169a451ea99.html
https://segmentfault.com/a/1190000019414444?utm_source=tag-newest
https://www.jianshu.com/p/9a90ca0fc24f
https://www.cnblogs.com/welan/p/9124081.html
Python 设计模式之建造者模式 Builder Pattern的更多相关文章
- 乐在其中设计模式(C#) - 建造者模式(Builder Pattern)
原文:乐在其中设计模式(C#) - 建造者模式(Builder Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 建造者模式(Builder Pattern) 作者:webabc ...
- 【设计模式】建造者模式 Builder Pattern
前面学习了简单工厂模式,工厂方法模式以及抽象工厂模式,这些都是创建类的对象所使用的一些常用的方法和套路, 那么如果我们创建一个很复杂的对象可上面的三种方法都不太适合,那么“专业的事交给专业人去做”,2 ...
- 二十四种设计模式:建造者模式(Builder Pattern)
建造者模式(Builder Pattern) 介绍将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 示例用同样的构建过程创建Sql和Xml的Insert()方法和Get()方 ...
- 设计模式-05建造者模式(Builder Pattern)
1.模式动机 比如我们要组装一台电脑,都知道电脑是由 CPU.主板.内存.硬盘.显卡.机箱.显示器.键盘和鼠标组成,其中非常重要的一点就是这些硬件都是可以灵活选择,但是组装步骤都是大同小异(可以组一个 ...
- 【UE4 设计模式】建造者模式 Builder Pattern
概述 描述 建造者模式,又称生成器模式.是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 建造者模式将客户端与包含多个组成部分的复杂对象的创建过程分离,客户端无需知道复杂 ...
- 【原】iOS设计模式之:建造者模式Builder Pattern,用于改进初始化参数
本文主要讨论一下iOS中的Builder Pattern.与网上很多版本不同,本文不去长篇大论地解释建造者模式的概念,那些东西太虚了.设计模式这种东西是为了解决实际问题的,不能为了设计模式而设计模式, ...
- iOS设计模式之:建造者模式Builder Pattern,用于改进初始化参数
转自:http://www.cnblogs.com/wengzilin/p/4365855.html 本文主要讨论一下iOS中的Builder Pattern.与网上很多版本不同,本文不去长篇大论地解 ...
- 设计模式系列之建造者模式(Builder Pattern)——复杂对象的组装与创建
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- python设计模式之建造者模式
python设计模式之建造者模式 建造者模式的适用范围:想要创建一个由多个部分组成的对象,而且它的构成需要一步接一步的完成.只有当各个部分都完成了,这个对象才完整.建造者模式表现为复杂对象的创建与 ...
随机推荐
- Linux 曝出严重安全漏洞,受限用户亦可提权至 Root 身份运行任意命令!(内附解决方案)
本文首发于:微信公众号「运维之美」,公众号 ID:Hi-Linux. 「运维之美」是一个有情怀.有态度,专注于 Linux 运维相关技术文章分享的公众号.公众号致力于为广大运维工作者分享各类技术文章和 ...
- 【HICP Gauss】数据库 环境的搭建 -1
1.安装规则 1.主机名必须网络唯一 2.主机名必须两位数以上 可以中划线 不能下划线 3.固定IP地址 4.端口号 1888 新增账户 omm 用户组 dbgrp ,家目录 /home/ ...
- 快速搭建Kerberos服务端及入门使用
快速搭建Kerberos服务端及入门使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Kerberos是一种网络身份验证协议.它旨在通过使用秘密密钥加密为客户端/服务器应用程序提 ...
- [转]Linux虚拟网络设备之tun/tap
转, 原文:https://segmentfault.com/a/1190000009249039 -------------------------------------------------- ...
- vue 博客知识点汇总
1. vue修改url,页面不刷新 项目中经常会用到同一个页面,结构是相同的,我只是在vue-router中通过添加参数的方式来区分状态,参数可以在页面跳转时带上params,或者query,但是有一 ...
- java8中的流操作
https://www.ibm.com/developerworks/cn/java/j-experience-stream/index.html Stream 流是 Java 8 新提供给开发者的一 ...
- for循环中嵌套异步请求问题
for循环中嵌套了异步请求会导致顺序错乱,用递归代替for循环,可以保证正常执行顺序:
- VS Code中配置Markdown
其实,对我来说是反过来的,我是为了使用Markdown而安装VS Code(虽然久仰大名) 安装VS Code 安装Markdown插件 使用篇 1. 安装vscode 之所以啰嗦一下,是因为据说安装 ...
- Kubernetes 学习16 RBAC
一.概述 1.前面讲过,kubernetes的授权也是基于插件来实现而且用户访问时某一次操作经由某一授权插件检查能通过后就不再经由其它插件检查.然后由准入控制插件再做进一步后续的准入控制检查.那么在他 ...
- 99: AGC-018C 堆+思维
$des$有 $X + Y + Z$ 个人,第 $i$ 个人有 $A_i$ 个金币,$B_i$ 个银币,$C_i$ 个铜币.选出 $X$ 个人获得其金币,选出 $Y$ 个人获得其银币,选出 $Z$ 个 ...