建造者模式(生成器模式、Buidler Pattern)和抽象工厂模式的目的都是用来创建复杂的对象,但是创建的过程是截然不同的。
- 在抽象工厂模式中,抽象出了创建方法,使用者只能按照预定好的步骤新创建一个对象。
- 在建造者模式中,使用者可以按照自己的想法,在合理的范围内定制自己所需要的对象。
所以当有一下情况时候,需要考虑使用建造者模式:
- 对象的创建步骤可以独立于创建过程的时候
- 被创建的对象拥有不同的表现形式
举一个栗子,我现在要买一台新版 15 寸的 Macbook Pro,打开官网发现有标准版和定制版两种可以选择。
所以现在有两种选择,购买标准版和购买定制版,定制版可以 SSD 升级到 1TB,可以把 CPU 升级到 2.7GHz,但是不允许升级内存到 32G,因为苹果说 32G 内存效果提升不大,还更加耗电。
这么一来我们就可在合理的范围内定制一台适合自己的笔记本。和购买标准版的结果一样,最后的结果都是可以获得一台新的 Macbook Pro。
类比到建造者模式和抽象工厂模式就是定制版和标准版。
总结一句话:建造者模式注重一步一步创建对象,抽象工厂模式注重一步到位创建对象。
建造者由 Director 和 Builder 构成,Builder 用于抽象各个对象部件的接口,Director 用于构造一个 Builder 的接口,由 Director 去指导 Builder 如何生成一个复杂对象。
代码描述
以购买一台 2016 款 15 寸 Macbook Pro 为背景描述一个建造者模式。
我们在线购买时候 online shop 就是一个 Director,它一步一步指导我们去购买一个 Macbook Pro。
from collections import namedtuple
class OnlineShop(object):
def __init__(self, buidler):
Macbook = namedtuple('Macbook', 'cpu memory ssd graphics')
self.macbook = Macbook(buidler.cpu, buidler.memory,
buidler.ssd, buidler.graphics)
def __str__(self):
return str(self.macbook)
class MacbookBuilder(object):
def __init__(self):
self.cpu = '2.7GHz'
self.memory = '16G'
self.ssd = '512GB'
self.graphics = 'Radeon Pro 455'
def upgrade_cpu(self, cpu):
self.cpu = cpu
return self
def upgrade_memory(self, memory):
raise ValueError('{0} is max'.format(self.memory))
def upgrade_ssd(self, ssd):
self.ssd = ssd
return self
def upgrade_graphics(self, graphics):
self.graphics = graphics
return self复制代码
OnlineShop 作为一个 Director 被客户端调用,MacbookBuilder 作为一个 Builder 是不能被客户端调用,只能被 Director 所调用,直接在类中定义另一个类,是防止被调用的简洁实现方式。
>>> macbook = OnlineShop.MacbookBuilder()\
.upgrade_cpu('2.9GHz')\
.upgrade_ssd('2TB')\
.upgrade_graphics('Radeon Pro 460')\
.build_up()
>>> print(macbook)
Macbook(cpu='2.9GHz', memory='16G', ssd='2TB', graphics='Radeon Pro 460')复制代码
如果不喜欢链式调用方式,不返回 self 即可
我们根据自己的需求添加配置,定制了一台 Macbook Pro 电脑的实例,在建造者模式中,需要定义一系列可供选择的方法去丰富实例,实现一个复杂的对象。