在軟件開發過程當中有時須要建立一個複雜的對象,這個複雜對象一般由多個子部件按必定的步驟組合而成。如遊戲中的不一樣角色,其性別、個性、能力、臉型、體型、服裝、髮型等特性都有所差別;還有汽車中的方向盤、發動機、車架、輪胎等部件也多種多樣;每封電子郵件的發件人、收件人、主題、內容、附件等內容也各不相同。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)模式在應用過程當中能夠根據須要改變,若是建立的產品種類只有一種,只須要一個具體建造者,這時能夠省略掉抽象建造者,甚至能夠省略掉指揮者角色。