优点:易于交换“产品系列”,只要更改相应的工厂即可。
缺点:建立产品的时候很繁琐,需要增加和修改很多东西。
优化1:为了避免客户端有过多的逻辑判断,可以封装出一个简单工厂类来生成产品类。
优化2:为了减少简单工厂类里面的逻辑判断,可以采用“反射”机制,直接根据外部的配置文件读取出需要使用产品类的信息。
#encoding=utf-8 # #by panda #抽象工厂模式 def printinfo(info): print unicode(info, 'utf-8').encode('gbk') #抽象产品a:user表 class iuser(): def insert(self): pass def getuser(self): pass #sqlserver实现的user class sqlserveruser(iuser): def insert(self): printinfo(在sql server中给user表增加一条记录) def getuser(self): printinfo(在sql server中得到user表的一条记录) #access实现的user class accessuser(iuser): def insert(self): printinfo(在access中给user表增加一条记录) def getuser(self): printinfo(在access中得到user表一条记录) #抽象产品b:部门表 class idepartment(): def insert(self): pass def getuser(self): pass #sqlserver实现的department class sqlserverdepartment(iuser): def insert(self): printinfo(在sql server中给department表增加一条记录) def getuser(self): printinfo(在sql server中得到department表的一条记录) #access实现的department class accessdepartment(iuser): def insert(self): printinfo(在access中给department表增加一条记录) def getuser(self): printinfo(在access中得到department表一条记录) #抽象工厂 class ifactory(): def createuser(self): pass def createdepartment(self): pass #sql server工厂 class sqlserverfactory(ifactory): def createuser(self): return sqlserveruser() def createdepartment(self): return sqlserverdepartment() #access工厂 class accessfactory(ifactory): def createuser(self): return accessuser() def createdepartment(self): return accessdepartment() #优化一:采用一个简单工厂类,封装逻辑判断操作 class dataaccess(): # db = sqlserver db = access @staticmethod def createuser(): if (dataaccess.db == sqlserver): return sqlserveruser() elif(dataaccess.db == access): return accessuser() @staticmethod def createdepartment(): if (dataaccess.db == sqlserver): return sqlserverdepartment() elif(dataaccess.db == access): return accessdepartment() #优化二:采用反射机制,避免使用太多判断 ##以下信息可以从配置文件中获取 dbtype = 'sqlserver' #'access' dbtab_user = 'user' dbtab_department = 'department' class dataaccesspro(): # db = sqlserver db = access @staticmethod def createuser(): funname = dbtype + dbtab_user return eval(funname)() #eval 将其中的字符串转化为python表达式 @staticmethod def createdepartment(): funname = dbtype + dbtab_department return eval(funname)() def clientui(): printinfo(\n--------抽象工厂方法--------) factory = sqlserverfactory() iu = factory.createuser() iu.insert() iu.getuser() id = factory.createdepartment() id.insert() id.getuser() printinfo(\n--抽象工厂方法+简单工厂方法--) iu = dataaccess.createuser() iu.insert() iu.getuser() id = dataaccess.createdepartment() id.insert() id.getuser() printinfo(\n-抽象工厂方法+简单工厂方法+反射-) iu = dataaccesspro.createuser() iu.insert() iu.getuser() id = dataaccesspro.createdepartment() id.insert() id.getuser() return if __name__ == '__main__': clientui();
类图:
工厂模式和抽象工厂模式的区别:工厂模式是在派生类中定义一个工厂的抽象接口,然后基类负责创建具体对象;抽象工厂模式是维护一个产品家族,由基类定义产品被生产的方法,客户根据派生类的接口进行开发。
实例:人民群众喜闻乐见的披萨店例子这里又可以搬出来了,这次我们根据抽象工厂模式的特点,用不同原材料制作不同口味的披萨,创建不同原材料的工厂,不同实体店做出口味不同的披萨。创建一个产品家族(dough、sauce、cheese和clam)的抽象类型(pizzaingredientfactory),这个类型的子类(nypizzaingredientfactory和chicagopizzaingredientfactory)定义了产品被产生的方法。
代码:
#!/usr/bin/python# -*- coding:utf-8 -*-import sysreload(sys)sys.setdefaultencoding('utf-8') '''披萨'''class pizza: name = dough = none sauce = none cheese = none clam = none def prepare(self): pass def bake(self): print 烘烤25分钟在350。.decode('utf-8') def cut(self): print 切割成对角线切片。.decode('utf-8') def box(self): print 放在官方的盒子中。.decode('utf-8') def get_name(self): return self.name def set_name(self, name): self.name = name def to_string(self): string = %s:\n % self.name string += 面团: %s\n % self.dough.to_string() if self.dough else string += 酱汁: %s\n % self.sauce.to_string() if self.sauce else string += 奶酪: %s\n % self.cheese.to_string() if self.cheese else string += 文蛤: %s\n % self.clam.to_string() if self.clam else return string '''什么类别的披萨'''class cheesepizza(pizza): def __init__(self, ingredient_factory): self.ingredient_factory = ingredient_factory def prepare(self): print 准备: %s % self.name self.dough = self.ingredient_factory.create_dough() self.sauce = self.ingredient_factory.create_sauce() self.cheese = self.ingredient_factory.create_cheese() class clampizza(pizza): def __init__(self, ingredient_factory): self.ingredient_factory = ingredient_factory def prepare(self): print 准备: %s % self.name self.dough = self.ingredient_factory.create_dough() self.sauce = self.ingredient_factory.create_sauce() self.clam = self.ingredient_factory.create_clam() '''披萨店'''class pizzastore: def order_pizza(self, pizza_type): self.pizza = self.create_pizza(pizza_type) self.pizza.prepare() self.pizza.bake() self.pizza.cut() self.pizza.box() return self.pizza def create_pizza(self, pizza_type): pass '''纽约披萨实体店1'''class nypizzastore(pizzastore): def create_pizza(self, pizza_type): ingredient_factory = nypizzaingredientfactory() if pizza_type == cheese: pizza = cheesepizza(ingredient_factory) pizza.set_name(纽约风格芝士披萨.decode('utf-8')) elif pizza_type == clam: pizza = clampizza(ingredient_factory) pizza.set_name(纽约风格文蛤披萨.decode('utf-8')) else: pizza = none return pizza '''芝加哥披萨实体店2'''class chicagopizzastore(pizzastore): def create_pizza(self, pizza_type): ingredient_factory = chicagopizzaingredientfactory() if pizza_type == cheese: pizza = cheesepizza(ingredient_factory) pizza.set_name(芝加哥风格芝士披萨.decode('utf-8')) elif pizza_type == clam: pizza = clampizza(ingredient_factory) pizza.set_name(芝加哥风格文蛤披萨.decode('utf-8')) else: pizza = none return pizza '''生产披萨的工厂'''class pizzaingredientfactory: def create_dough(self): pass def create_sauce(self): pass def create_cheese(self): pass def create_clam(self): pass '''生产披萨的实体工厂1'''class nypizzaingredientfactory(pizzaingredientfactory): def create_dough(self): return thindough() def create_sauce(self): return marinarasauce() def create_cheese(self): return freshcheese() def create_clam(self): return freshclam() '''生产披萨的实体工厂2'''class chicagopizzaingredientfactory(pizzaingredientfactory): def create_dough(self): return thickdough() def create_sauce(self): return mushroomsauce() def create_cheese(self): return bluecheese() def create_clam(self): return frozenclam() class dough: def to_string(self): pass class thindough(dough): def to_string(self): return 薄的面团 class thickdough(dough): def to_string(self): return 厚的生面团 class sauce: def to_string(self): pass class marinarasauce(sauce): def to_string(self): return 番茄酱 class mushroomsauce(sauce): def to_string(self): return 蘑菇酱 class cheese: def to_string(self): pass class freshcheese(cheese): def to_string(self): return 新鲜的奶酪 class bluecheese(cheese): def to_string(self): return 蓝纹奶酪 class clam: def to_string(self): pass class freshclam(clam): def to_string(self): return 新鲜的文蛤 class frozenclam(clam): def to_string(self): return 冷冻的文蛤 if __name__ == __main__: # 创建了两个披萨实体店 ny_store = nypizzastore() chicago_store = chicagopizzastore() # 在第一个披萨对象中订购了一个cheese风味的披萨 pizza = ny_store.order_pizza(cheese) print pizza.to_string() print 迈克订购了一个 %s % pizza.get_name() print pizza = chicago_store.order_pizza(clam) print pizza.to_string() print 约翰订购了一个%s % pizza.get_name()
结果:
准备: 纽约风格芝士披萨烘烤25分钟在350。切割成对角线切片。放在官方的盒子中。纽约风格芝士披萨: 面团: 薄的面团 酱汁: 番茄酱 奶酪: 新鲜的奶酪 迈克订购了一个 纽约风格芝士披萨 准备: 芝加哥风格文蛤披萨烘烤25分钟在350。切割成对角线切片。放在官方的盒子中。芝加哥风格文蛤披萨: 面团: 厚的生面团 酱汁: 蘑菇酱 文蛤: 冷冻的文蛤 约翰订购了一个芝加哥风格文蛤披萨