第2篇---Python设计模式之抽象工厂模式+含代码实现+学习python的小哥哥小姐姐一定要看看
抽象工厂概念
提供一个创建一系列相关或者相互依赖对象的接口。而无需指定它们具体的类。。 。。可能还是一头雾水。学习完下面两个案例,你就清楚了。
案例1
想像一下,我们现在要研究一款老少皆宜的游戏。 少儿登录后的游戏场景是:主人公是青蛙,喜欢吃虫子。大人登录后的游戏场景是:男巫战怪兽。 在运行时,基于用户输入,决定该创建那个游戏并运行。 游戏的创建部分由一个抽象工厂维护。
# 小孩子的模式
class Frog: # 青蛙类 可以设置名字
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
def interact_with(self, obstacle):
print('{} the Frog encounter {} 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------Frog 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('{} 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: # 所谓的抽象工厂:就是根据我们传入的factory对象,然后开启不同生成不同游戏中的任务
def __init__(self, factory):
self.hero = factory.make_character()
self.obstacle = factory.make_obstacle()
def play(self):
self.***teract_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)
if __name__ == '__main__':
name = input('Hello. What is your 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()
解析: 上述代码中GameEnvironment类起的就是一个抽象工厂的作用 。。 我们根据年龄的不同,生成不同游戏场景的实例。然后将实例传给GameEnvironment ,让他生成游戏中不同的人物。最后让青蛙打虫子等。。
上述代码的输出结果:
案例2:
我们现在有两种数据库, 分别为Sqlserver和Access数据库。。这两个数据库中分别有两张表,分别为用户表,部门表。。我们想要做的就是可以随便切换数据库 ,进行当前数据库中数据的修改。
# 针对不同数据库,我们创建不同的访问用户
from abc import ABCMeta, abstractmethod
# 用户表
class IUser(metaclass=ABCMeta): # 相当于接口,这个代表一张表
@abstractmethod
def insert(self): # 在数据库中给用户表插入数据
pass
@abstractmethod
def getUser(self): # 在数据库中获取用户表的记录
pass
# 在Sqlserver数据库创建用户表
class SqlserverUser(IUser):
def insert(self):
print("在Sqlserver的用户表中插入一条数据咯")
def getUser(self):
print("在Sqlserver中得到一条用户表的记录")
# 在Access数据库创建用户表
class AccessUser(IUser):
def insert(self):
print("在Access的用户表中插入一条数据咯")
def getUser(self):
print("在Access中得到一条用户表的记录")
# 再搞一个表 部门表
class IDepartment(metaclass=ABCMeta):
@abstractmethod
def insert(self): # 在数据库中为部门表插入记录
pass
@abstractmethod
def getDepartment(self): # 获取部门表中的记录
pass
# 在Sqlserver数据库创建用户表
class SqlserverDepartment(IDepartment):
def insert(self):
print("在Sqlserver的部门表中插入一条数据咯")
def getDepartment(self):
print("在Sqlserver中得到一条部门表的记录")
# 在Access数据库创建用户表
class AccessDepartment(IDepartment):
def insert(self):
print("在Access的部门表中插入一条数据咯")
def getDepartment(self):
print("在Access中得到一条部门表的记录")
# 抽象工厂
class IFactory(metaclass=ABCMeta):
@abstractmethod
def createUser(self): # 创建用户表
pass
@abstractmethod
def createDepartment(self): # 创建部门表
pass
class SqlServerFactory(IFactory):
def createUser(self):
return SqlserverUser()
def createDepartment(self):
return SqlserverDepartment()
class AccessFactory(IFactory):
def createUser(self):
return AccessUser()
def createDepartment(self):
return AccessDepartment()
def caozuo_user(factory): # 操作用户表
iu = factory.createUser()
iu.insert()
iu.getUser()
def caozuo_department(factory): # 操作部门表
ide = factory.createDepartment()
ide.insert()
ide.getDepartment()
if __name__ == '__main__':
print("对Access数据库的操作。")
factory = AccessFactory() # 在这里换数据库
caozuo_user(factory) # 操作用户表
caozuo_department(factory) # 操作部门表
print('\n')
print("对SqlServer数据库的操作。")
factory = SqlServerFactory() # 在这里换数据库
caozuo_user(factory) # 操作用户表
caozuo_department(factory) # 操作部门表
这里的SqlServerFactory和AccessFactory相当于我们第一个例子中的FrogWorld和WizardWorld 针对不同的情况,创建不同的对象。。第二个例子还可以再进行封装。这里我就不做了。。大家仿照第一个例子进行改进。
输出结果: