在软件开发过程当中有时须要建立一个复杂的对象,这个复杂对象一般由多个子部件按必定的步骤组合而成。如游戏中的不一样角色,其性别、个性、能力、脸型、体型、服装、发型等特性都有所差别;还有汽车中的方向盘、发动机、车架、轮胎等部件也多种多样;每封电子邮件的发件人、收件人、主题、内容、附件等内容也各不相同。python
以上全部这些产品都是由多个部件构成的,各个部件能够灵活选择,但其建立步骤都大同小异。这类产品的建立没法用前面介绍的工厂模式描述,只有建造者模式能够很好地描述该类产品的建立。算法
建造者(Builder)模式的定义:指将一个复杂对象的构造与它的表示分离,使一样的构建过程能够建立不一样的表示,这样的设计模式被称为建造者模式。设计模式
它是将一个复杂的对象分解为多个简单的对象,而后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是能够灵活选择的。布局
该模式的主要优势以下:ui
其缺点以下:spa
建造者(Builder)模式和工厂模式的关注点不一样:建造者模式注重零部件的组装过程,而工厂方法模式更注重零部件的建立过程,但二者能够结合使用。设计
建造者(Builder)模式由产品、抽象建造者、具体建造者、指挥者等 4 个要素构成,如今咱们来分析其基本结构和实现方法。code
建造者(Builder)模式的主要角色以下。对象
上图给出了建造者(Builder)模式的主要结构,其相关类的代码以下。blog
(1) 产品角色:包含多个组成部件的复杂对象。
class Product(object): '''产品类''' __part_a = "" __part_b = "" __part_c = "" @property def part_a(self): return self.__part_a @part_a.setter def part_a(self, a): self.__part_a = a @property def part_b(self): return self.__part_b @part_b.setter def part_b(self, b): self.__part_b = b @property def part_c(self): return self.__part_c @part_c.setter def part_c(self, c): self.__part_c = c def show(self): '''显示产品特性''' print(self.__part_a) print(self.__part_b) print(self.__part_c)
(2) 抽象建造者:包含建立产品各个子部件的抽象方法。
class AbstractBuilder(object): '''抽象建造者''' product = Product() def build_part_a(self): '''抽象方法''' pass def build_part_b(self): '''抽象方法''' pass def build_part_c(self): '''抽象方法''' pass def get_result(self): return self.product
(3) 具体建造者:实现了抽象建造者接口。
class ConcreteBuilder1(AbstractBuilder): '''具体建造者''' def build_part_a(self): self.product.part_a = "Builder1 建造 PartA" def build_part_b(self): self.product.part_b = "Builder1 建造 PartB" def build_part_c(self): self.product.part_c = "Builder1 建造 PartC" class ConcreteBuilder2(AbstractBuilder): def build_part_a(self): self.product.part_a = "Builder2 建造 PartA" def build_part_b(self): self.product.part_b = "Builder2 建造 PartB" def build_part_c(self): self.product.part_c = "Builder2 建造 PartC"
(4) 指挥者:调用建造者中的方法完成复杂对象的建立。
class Director(object): _builder = None # Type -> Builder def __init__(self, builder): self._builder = builder def construct(self): '''产品的构建与组装''' self._builder.build_part_a() self._builder.build_part_b() self._builder.build_part_c() return self._builder.get_result()
(5) 客户类。
if __name__ == '__main__': builder = ConcreteBuilder1() director = Director(builder) product = director.construct() product.show()
运行结果:
Builder1 建造 PartA Builder1 建造 PartB Builder1 建造 PartC
【例1】用建造者(Builder)模式描述客厅装修。
分析:客厅装修是一个复杂的过程,它包含墙体的装修、电视机的选择、沙发的购买与布局等。客户把装修要求告诉项目经理,项目经理指挥装修工人一步步装修,最后完成整个客厅的装修与布局,因此本实例用建造者模式实现比较适合。
这里客厅是产品,包括墙、电视和沙发等组成部分。具体装修工人是具体建造者,他们负责装修与墙、电视和沙发的布局。项目经理是指挥者,他负责指挥装修工人进行装修。
class Parlour(object): '''客厅类''' __wall = "" __TV = "" __sofa = "" @property def wall(self): return self.__wall @wall.setter def wall(self, wall): self.__wall = wall @property def TV(self): return self.__TV @TV.setter def TV(self, TV): self.__TV = TV @property def sofa(self): return self.__sofa @sofa.setter def sofa(self, sofa): self.__sofa = sofa def show(self): print(self.__wall) print(self.__TV) print(self.__sofa) class AbstractDecorator(object): '''抽象装修工人类''' parlour = Parlour() def build_wall(self): pass def build_TV(self): pass def build_sofa(self): pass def get_result(self): return self.parlour class ConcreteDecorator1(AbstractDecorator): def build_wall(self): self.parlour.wall = "红色墙" def build_TV(self): self.parlour.TV = "红色电视" def build_sofa(self): self.parlour.sofa = "红色沙发" class ConcreteDecorator2(AbstractDecorator): def build_wall(self): self.parlour.wall = "蓝色墙" def build_TV(self): self.parlour.TV = "蓝色电视" def build_sofa(self): self.parlour.sofa = "蓝色沙发" class ProjrctManager(object): _decorator = None def __init__(self, decorator): self._decorator = decorator def construct(self): self._decorator.build_wall() self._decorator.build_TV() self._decorator.build_sofa() return self.__decorator.get_result() if __name__ == '__main__': decorator = ConcreteDecorator1() manager = ProjrctManager(decorator) parlour = manager.construct() parlour.show()
红色墙 红色电视 红色沙发
建造者(Builder)模式建立的是复杂对象,其产品的各个部分常常面临着剧烈的变化,但将它们组合在一块儿的算法却相对稳定,因此它一般在如下场合使用。
建造者(Builder)模式在应用过程当中能够根据须要改变,若是建立的产品种类只有一种,只须要一个具体建造者,这时能够省略掉抽象建造者,甚至能够省略掉指挥者角色。