舉例講解Python設(shè)計(jì)模式編程中對抽象工廠模式的運(yùn)用
抽象工廠模式:提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對象的接口,而無需指定它們具體的類。
優(yōu)點(diǎn):易于交換“產(chǎn)品系列”,只要更改相應(yīng)的工廠即可。
缺點(diǎn):建立產(chǎn)品的時(shí)候很繁瑣,需要增加和修改很多東西。
優(yōu)化1:為了避免客戶端有過多的邏輯判斷,可以封裝出一個(gè)簡單工廠類來生成產(chǎn)品類。
優(yōu)化2:為了減少簡單工廠類里面的邏輯判斷,可以采用“反射”機(jī)制,直接根據(jù)外部的配置文件讀取出需要使用產(chǎn)品類的信息。
#encoding=utf-8 # #by panda #抽象工廠模式 def printInfo(info): print unicode(info, 'utf-8').encode('gbk') #抽象產(chǎn)品A:user表 class IUser(): def Insert(self): pass def GetUser(self): pass #sqlserver實(shí)現(xiàn)的User class SqlserverUser(IUser): def Insert(self): printInfo("在SQL Server中給User表增加一條記錄") def GetUser(self): printInfo("在SQL Server中得到User表的一條記錄") #Access實(shí)現(xiàn)的User class AccessUser(IUser): def Insert(self): printInfo("在Access中給User表增加一條記錄") def GetUser(self): printInfo("在Access中得到User表一條記錄") #抽象產(chǎn)品B:部門表 class IDepartment(): def Insert(self): pass def GetUser(self): pass #sqlserver實(shí)現(xiàn)的Department class SqlserverDepartment(IUser): def Insert(self): printInfo("在SQL Server中給Department表增加一條記錄") def GetUser(self): printInfo("在SQL Server中得到Department表的一條記錄") #Access實(shí)現(xiàn)的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() #優(yōu)化一:采用一個(gè)簡單工廠類,封裝邏輯判斷操作 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() #優(yōu)化二:采用反射機(jī)制,避免使用太多判斷 ##以下信息可以從配置文件中獲取 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 將其中的字符串轉(zhuǎn)化為python表達(dá)式 @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();
類圖:
工廠模式和抽象工廠模式的區(qū)別:工廠模式是在派生類中定義一個(gè)工廠的抽象接口,然后基類負(fù)責(zé)創(chuàng)建具體對象;抽象工廠模式是維護(hù)一個(gè)產(chǎn)品家族,由基類定義產(chǎn)品被生產(chǎn)的方法,客戶根據(jù)派生類的接口進(jìn)行開發(fā)。
實(shí)例:人民群眾喜聞樂見的披薩店例子這里又可以搬出來了,這次我們根據(jù)抽象工廠模式的特點(diǎn),用不同原材料制作不同口味的披薩,創(chuàng)建不同原材料的工廠,不同實(shí)體店做出口味不同的披薩。創(chuàng)建一個(gè)產(chǎn)品家族(Dough、Sauce、Cheese和Clam)的抽象類型(PizzaIngredientFactory),這個(gè)類型的子類(NYPizzaIngredientFactory和ChicagoPizzaIngredientFactory)定義了產(chǎn)品被產(chǎn)生的方法。
代碼:
#!/usr/bin/python # -*- coding:utf-8 -*- import sys reload(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 += " 面團(tuán): %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 "準(zhǔn)備: %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 "準(zhǔn)備: %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 ''' 紐約披薩實(shí)體店1 ''' class NYPizzaStore(PizzaStore): def create_pizza(self, pizza_type): ingredient_factory = NYPizzaIngredientFactory() if pizza_type == "cheese": pizza = CheesePizza(ingredient_factory) pizza.set_name("紐約風(fēng)格芝士披薩".decode('utf-8')) elif pizza_type == "clam": pizza = ClamPizza(ingredient_factory) pizza.set_name("紐約風(fēng)格文蛤披薩".decode('utf-8')) else: pizza = None return pizza ''' 芝加哥披薩實(shí)體店2 ''' class ChicagoPizzaStore(PizzaStore): def create_pizza(self, pizza_type): ingredient_factory = ChicagoPizzaIngredientFactory() if pizza_type == "cheese": pizza = CheesePizza(ingredient_factory) pizza.set_name("芝加哥風(fēng)格芝士披薩".decode('utf-8')) elif pizza_type == "clam": pizza = ClamPizza(ingredient_factory) pizza.set_name("芝加哥風(fēng)格文蛤披薩".decode('utf-8')) else: pizza = None return pizza ''' 生產(chǎn)披薩的工廠 ''' class PizzaIngredientFactory: def create_dough(self): pass def create_sauce(self): pass def create_cheese(self): pass def create_clam(self): pass ''' 生產(chǎn)披薩的實(shí)體工廠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() ''' 生產(chǎn)披薩的實(shí)體工廠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 "薄的面團(tuán)" class ThickDough(Dough): def to_string(self): return "厚的生面團(tuán)" 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 "藍(lán)紋奶酪" 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__": # 創(chuàng)建了兩個(gè)披薩實(shí)體店 ny_store = NYPizzaStore() chicago_store = ChicagoPizzaStore() # 在第一個(gè)披薩對象中訂購了一個(gè)cheese風(fēng)味的披薩 pizza = ny_store.order_pizza("cheese") print pizza.to_string() print "邁克訂購了一個(gè) %s" % pizza.get_name() print pizza = chicago_store.order_pizza("clam") print pizza.to_string() print "約翰訂購了一個(gè)%s" % pizza.get_name()
結(jié)果:
準(zhǔn)備: 紐約風(fēng)格芝士披薩 烘烤25分鐘在350。 切割成對角線切片。 放在官方的盒子中。 紐約風(fēng)格芝士披薩: 面團(tuán): 薄的面團(tuán) 醬汁: 番茄醬 奶酪: 新鮮的奶酪 邁克訂購了一個(gè) 紐約風(fēng)格芝士披薩 準(zhǔn)備: 芝加哥風(fēng)格文蛤披薩 烘烤25分鐘在350。 切割成對角線切片。 放在官方的盒子中。 芝加哥風(fēng)格文蛤披薩: 面團(tuán): 厚的生面團(tuán) 醬汁: 蘑菇醬 文蛤: 冷凍的文蛤 約翰訂購了一個(gè)芝加哥風(fēng)格文蛤披薩
相關(guān)文章
基于Python實(shí)現(xiàn)一個(gè)簡單的注冊機(jī)并生成卡密
這篇文章主要為大家詳細(xì)介紹了如何使用Python編寫一個(gè)簡單而強(qiáng)大的注冊機(jī),生成卡密來實(shí)現(xiàn)用戶注冊,從而輕松登錄應(yīng)用程序,有需要的小伙伴快可以參考下2023-12-12Python?數(shù)據(jù)可視化實(shí)現(xiàn)5種炫酷的動(dòng)態(tài)圖
數(shù)據(jù)可以幫助我們描述這個(gè)世界、闡釋自己的想法和展示自己的成果,但如果只有單調(diào)乏味的文本和數(shù)字,我們卻往往能難抓住觀眾的眼球。而很多時(shí)候,一張漂亮的可視化圖表就足以勝過千言萬語2022-01-01python3+pyqt5+itchat微信定時(shí)發(fā)送消息的方法
今天小編就為大家分享一篇python3+pyqt5+itchat微信定時(shí)發(fā)送消息的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-02-02Python中super()的理解以及應(yīng)用場景實(shí)例
在python中關(guān)于類的定義可以分為兩種:老式類&新式類,在新式類中有這么一種方法super( ),下面這篇文章主要給大家介紹了關(guān)于Python中super()的理解以及應(yīng)用場景的相關(guān)資料,需要的朋友可以參考下2021-09-09