第二天:创建型模式--抽象工厂模式
零、抽象工厂
- 什么是抽象工厂
抽象工厂设计模式是抽象方法的一种泛化,一个抽象工厂是一组工厂方法,每个工厂方法负责产生不同种类的对象。
一、身边的例子
- 生产汽车部件
冲压不同的部件用的机器是相同的。机器装配的模型是可配的,随时改变。 - 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()