來源:《設(shè)計(jì)模式 可復(fù)用面向?qū)ο筌浖幕A(chǔ)》 ---GoF
創(chuàng)建型模式
1. 抽象工廠
- 起源
用一組對(duì)象來實(shí)現(xiàn)一個(gè)功能,后來需要增加一組類似的對(duì)象來迭代這個(gè)功能陪踩,這時(shí)候我們可以拔高一層饲趋,用一個(gè)工廠來生成這一組對(duì)象,擴(kuò)展的時(shí)候,只需要新建一個(gè)工廠即可夫否。
- 代碼
class MazeFactory(object):
def make_maze(self):
return Maze()
def make_wall(self):
return Wall()
def make_room(self, n):
return Room(n)
def make_door(self, r1, r2):
return Door(r1, r2)
class EnchantedMazeFactory(MazeFactory):
def make_room(self, n):
return EnchantedRoom(n, CastSpell())
def make_door(self, r1, r2):
return DoorNeedingSpell(r1, r2)
def create_maze(factory):
a_maze = factory.make_maze()
r1 = factory.make_room(1)
r2 = factory.make_room(2)
a_door = factory.make_door(r1, r2)
# ...
return a_maze
- 注意
注意和工廠方法的聯(lián)系與區(qū)別
2. 生成器
- 起源
一個(gè)復(fù)雜對(duì)象的生成過程是固定的(如富文本展示,分析語法的過程是固定的)叫胁,但是展示結(jié)果是可以擴(kuò)展的凰慈,可以由一個(gè)生成器來生成展示結(jié)果對(duì)象,擴(kuò)展的時(shí)候只需要擴(kuò)展生成器即可驼鹅。
- 代碼
class MazeBuilder(object):
def build_maze(self):
pass
def build_room(self, room):
pass
def build_door(self, room_from, roomto):
pass
def get_maze(self):
return None
class StandarMazeBuilder(MazeBuilder):
def build_maze(self):
self._current_maze = Maze()
def build_room(self, n):
room = Room(n)
self._current_maze.add_room(room)
# ...
def get_maze(self):
return self._current_maze
def create_maze(builder):
builder.build_maze()
builder.build_room(1)
builder.build_room(2)
builder.build_door(1, 2)
return builder.get_maze()
def create_complex_maze(builder):
"""這里可以有不同的生成方式"""
builder.build_maze()
# ...
return builder.build_maze()
- 注意
其結(jié)構(gòu)和抽象工廠很類似微谓,但是他們的目的是不同的,抽象工廠是要使用工廠生成的一系列對(duì)象输钩,而生成器不需要中間對(duì)象豺型,只需要最終生成的結(jié)果。
思想就是模板方法的思想买乃,抽象層只定義算法的流程姻氨,實(shí)現(xiàn)層定義算法的細(xì)節(jié)。
3. 工廠方法
- 起源
一個(gè)框架需要一個(gè)對(duì)象來實(shí)現(xiàn)某個(gè)功能剪验,后來需要迭代肴焊,用另一個(gè)類似的對(duì)象來實(shí)現(xiàn)迭代后的功能,這時(shí)可以將這個(gè)對(duì)象的創(chuàng)建封裝為工廠方法功戚,由不同的子類決定生成不一樣的對(duì)象娶眷。
- 代碼
class MazeGame(object):
def create_maze(self):
a_maze = self.make_maze()
room = self.make_room(1)
# ...
return a_maze
### 下面全是工廠方法
def make_maze(self):
return Maze()
def make_room(self, n):
return Room(n)
class BombedMazeGame(MazeGame):
def make_room(self, n):
return RoomWithABomb(n)
- 注意
工廠方法是一種思想,重點(diǎn)在于方法疫铜,而不是工廠茂浮,所以它和抽象工廠不是互斥的關(guān)系,而是抽象工廠由工廠方法來實(shí)現(xiàn)壳咕。
4. 原型
- 起源
考慮像C++這樣的靜態(tài)語言席揽,如果希望動(dòng)態(tài)的增加某個(gè)工廠可產(chǎn)生的對(duì)象的種類,那么可以將需要增加的對(duì)象動(dòng)態(tài)注冊進(jìn)去谓厘,需要時(shí)返回該對(duì)象的拷貝即可幌羞。
- 注意
像python這樣的動(dòng)態(tài)語言,因?yàn)橛蓄悓?duì)象的概念竟稳,類可以當(dāng)作對(duì)象一樣傳遞属桦,所以該模式在這些語言中不是特別有用熊痴。
5. 單例
- 起源
一個(gè)系統(tǒng)中總會(huì)有一些對(duì)象只能實(shí)例化一個(gè),如果將其保存在全局變量中聂宾,并不能保證其他人不會(huì)多次實(shí)例化果善,所以一般會(huì)讓類自己保存這個(gè)唯一的實(shí)例化對(duì)象。