第二天:建立型模式--抽象工廠模式
阿新 • • 發佈:2019-02-14
零、抽象工廠
- 什麼是抽象工廠
抽象工廠設計模式是抽象方法的一種泛化,一個抽象工廠是一組工廠方法,每個工廠方法負責產生不同種類的物件。
一、身邊的例子
- 生產汽車部件
衝壓不同的部件用的機器是相同的。機器裝配的模型是可配的,隨時改變。 - django_factory
程式包 django_factory是一個用於在測試中建立Django模型的抽象工廠實現,可用來為支援測試專有屬性的模型建立例項。
二、什麼情況下使用
- 需要將物件的使用和建立解耦的時候;
- 需要提高應用的效能和記憶體使用率的時候;
- 建立物件的程式碼分佈在多個不同的地方,且不僅僅在一個方法中,導致無法跟蹤這些物件的時候。
三、何時使用抽象工廠 / 工廠方法
一開始使用工廠方法,在後期需要許多工廠方法,將建立一系列物件的過程合併在一起形成抽象工廠。抽象工廠有一個優點,在使用工廠方法是從使用者視角通常是看不到的,抽象工廠能夠通過改變啟用的工廠方法動態的改變應用的行為。
四、應用案例
# 青蛙類
class Frog:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
def interact_with(self, obstacle) :
print('{} the Forg encounters {} and {}!'.format(self, obstacle, obstacle.action()))
# 蟲子類
class Bug:
def __str__(self):
return 'a bug'
def action(self):
return 'eats it'
# 青蛙蟲子遊戲類
class FrogWorld:
def __init__(self, name):
print(self)
self.player_name = name
def __str__(self):
return '\n\n\t----- Forg World ------'
def make_character(self):
return Frog(self.player_name)
def make_obstacle(self):
return Bug()
# 巫師類
class Wizard:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
def interact_with(self, obstacle):
print(self)
print('{} the Wizard battles against {} and {}!'.format(self, obstacle, obstacle.action()))
# 怪獸類
class Ork:
def __str__(self):
return 'an evil ork'
def action(self):
return 'kills it'
# 巫師世界遊戲類
class WizardWorld:
def __init__(self, name):
print(self)
self.player_name = name
def __str__(self):
return '\n\n\t------ Wizard World ------'
def make_character(self):
return Wizard(self.player_name)
def make_obstacle(self):
return Ork()
# 遊戲入口類
class GameEnvironment:
def __init__(self, factory):
# 建立角色
self.hero = factory.make_character()
# 建立障礙物
self.obstacle = factory.make_obstacle()
def play(self):
self.hero.interact_with(self.obstacle)
# 驗證輸入的年齡
def validate_age(name):
try:
age = input('Welcome {}.How old are you ?'.format(name))
age = int(age)
except ValueError as err:
print("Age {} is invalid, please try again...".format(age))
return (False, age)
return (True, age)
def main():
name = input("Hello. What's tour name? ")
valid_input = False
while not valid_input:
valid_input, age = validate_age(name)
game = FrogWorld if age < 18 else WizardWorld
environment = GameEnvironment(game(name))
environment.play()
if __name__ == '__main__':
main()