python 实现 建造者模式

本文介绍了建造者设计模式在Python中的应用,通过比萨订购系统的例子展示了如何使用建造者模式创建复杂对象。文章讨论了建造者模式与工厂模式的区别,并提供了实现比萨制作的代码示例,包括玛格丽特比萨和奶油熏肉比萨的建造者。最后,对比了两种不同风格的建造者模式实现,并总结了何时选择建造者模式。
摘要由CSDN通过智能技术生成

本文目录地址

本文代码地址

想象一下,我们想要创建一个由多个部分构成的对象,而且它的构成需要一步接一步地完成。只有当各个部分都创建好,这个对象才算是完整的。这正是建造者设计模式(Builder design pattern)的用武之地。建造者模式将一个复杂对象的构造过程与其表现分离,这样,同一个构造过程可用于创建多个不同的表现。

我们来看个实际的例子,这可能有助于理解建造者模式的目的。假设我们想要创建一个HTML页面生成器,HTML页面的基本结构(构造组件)通常是一样的:以<html>开始</html>结束,在HTML部分中有<head>和</head>元素,在head部分中又有<title>和</title>元素,等等;但页面在表现上可以不同。每个页面有自己的页面标题、文本标题以及不同的<body>内容。此外,页面通常是经过多个步骤创建完成的:有一个函数添加页面标题,另一个添加主文本标题,还有一个添加页脚,等等。仅当一个页面的结构全部完成后,才能使用一个最终的渲染函数将该页面展示在客户端。我们甚至可以更进一步扩展这个HTML生成器,让它可以生成一些完全不同的HTML页面。一个页面可能包含表格,另一个页面可能包含图像库,还有一个页面包含联系表单,等等。

HTML页面生成问题可以使用建造者模式来解决。该模式中,有两个参与者:建造者(builder)和指挥者(director)。建造者负责创建复杂对象的各个组成部分。在HTML例子中,这些组成部分是页面标题、文本标题、内容主体及页脚。指挥者使用一个建造者实例控制建造的过程。对于HTML示例,这是指调用建造者的函数设置页面标题、文本标题等。使用不同的建造者实例让我们可以创建不同的HTML页面,而无需变更指挥者的代码。

目录

1.1应用案例

1.2实现

1.3小结


1.1应用案例

如果我们知道一个对象必须经过多个步骤来创建,并且要求同一个构造过程可以产生不同的表现,就可以使用建造者模式。这种需求存在于许多应用中,例如页面生成器(本章提到的HTML页面生成器之类)、文档转换器以及用户界面(User Interface,UI)表单创建工具。

有些资料提到建造者模式也可用于解决可伸缩构造函数问题。当我们为支持不同的对象创建方式而不得不创建一个新的构造函数时,可伸缩构造函数问题就发生了,这种情况最终产生许多构造函数和长长的形参列表,难以管理。Stack Overflow网站上列出了一个可伸缩构造函数的例子。幸运的是,这个问题在Python中并不存在,因为至少有以下两种方式可以解决这个问题。

  • 使用命名形参
  • 使用实参列表展开

在这一点上,建造者模式和工厂模式的差别并不太明确。主要的区别在于工厂模式以单个步骤创建对象,而建造者模式以多个步骤创建对象,并且几乎始终会使用一个指挥者。一些有针对性的建造者模式实现并未使用指挥者,如Java的StringBuilder,但这只是例外。

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

新电脑类比的例子也许有助于区分建造者模式和工厂模式。假设你想购买一台新电脑,如果决定购买一台特定的预配置的电脑型号,例如,最新的苹果1.4GHz Mac mini,则是在使用工厂模式。所有硬件的规格都已经由制造商预先确定,制造商不用向你咨询就知道自己该做些什么,它们通常接收的仅仅是单条指令。在代码级别上,看起来是下面这样的(apple-factory.py)。

MINI14='1.4GHz Mac mini'
class AppleFactory:
    class MacMini14:
        def __init__(self):
            self.memory=4
            self.hdd=500
            self.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)

输出

Model: 1.4GHz Mac mini
Memory: 4GB
Hard Disk: 500GB
Graphics Card: Intel HD Graphics 5000

注意:这里嵌套了MacMini14类。这是禁止直接实例化一个类的简洁方式。

另一个选择是购买一台定制的PC。假若这样,使用的即是建造者模式。你是指挥者,向制造商(建造者)提供指令说明心中理想的电脑规格。在代码方面,看起来是下面这样的(computer-builder.py)。

class Computer:
    def __init__(self,serial_number):
        self.serial=serial_number
        
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值