
舉例講解Python設(shè)計(jì)模式編程中對(duì)抽象工廠模式的運(yùn)用
這篇文章主要介紹了Python設(shè)計(jì)模式編程中對(duì)抽象工廠模式的運(yùn)用,文中的例子體現(xiàn)了抽象工廠模式程序的一些設(shè)計(jì)優(yōu)化點(diǎn),需要的朋友可以參考下
抽象工廠模式:提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口,而無(wú)需指定它們具體的類。
優(yōu)點(diǎn):易于交換“產(chǎn)品系列”,只要更改相應(yīng)的工廠即可。
缺點(diǎn):建立產(chǎn)品的時(shí)候很繁瑣,需要增加和修改很多東西。
優(yōu)化1:為了避免客戶端有過(guò)多的邏輯判斷,可以封裝出一個(gè)簡(jiǎn)單工廠類來(lái)生成產(chǎn)品類。
優(yōu)化2:為了減少簡(jiǎn)單工廠類里面的邏輯判斷,可以采用“反射”機(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è)簡(jiǎn)單工廠類,封裝邏輯判斷操作
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--抽象工廠方法+簡(jiǎn)單工廠方法--")
iu = DataAccess.CreateUser()
iu.Insert()
iu.GetUser()
id = DataAccess.CreateDepartment()
id.Insert()
id.GetUser()
printInfo("\n-抽象工廠方法+簡(jiǎ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)建具體對(duì)象;抽象工廠模式是維護(hù)一個(gè)產(chǎn)品家族,由基類定義產(chǎn)品被生產(chǎn)的方法,客戶根據(jù)派生類的接口進(jìn)行開(kāi)發(fā)。
實(shí)例:人民群眾喜聞樂(lè)見(jiàn)的披薩店例子這里又可以搬出來(lái)了,這次我們根據(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 "切割成對(duì)角線切片。".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è)披薩對(duì)象中訂購(gòu)了一個(gè)cheese風(fēng)味的披薩
pizza = ny_store.order_pizza("cheese")
print pizza.to_string()
print "邁克訂購(gòu)了一個(gè) %s" % pizza.get_name()
print
pizza = chicago_store.order_pizza("clam")
print pizza.to_string()
print "約翰訂購(gòu)了一個(gè)%s" % pizza.get_name()
結(jié)果:
準(zhǔn)備: 紐約風(fēng)格芝士披薩
烘烤25分鐘在350。
切割成對(duì)角線切片。
放在官方的盒子中。
紐約風(fēng)格芝士披薩:
面團(tuán): 薄的面團(tuán)
醬汁: 番茄醬
奶酪: 新鮮的奶酪
邁克訂購(gòu)了一個(gè) 紐約風(fēng)格芝士披薩
準(zhǔn)備: 芝加哥風(fēng)格文蛤披薩
烘烤25分鐘在350。
切割成對(duì)角線切片。
放在官方的盒子中。
芝加哥風(fēng)格文蛤披薩:
面團(tuán): 厚的生面團(tuán)
醬汁: 蘑菇醬
文蛤: 冷凍的文蛤
約翰訂購(gòu)了一個(gè)芝加哥風(fēng)格文蛤披薩
數(shù)據(jù)分析咨詢請(qǐng)掃描二維碼
若不方便掃碼,搜微信號(hào):CDAshujufenxi
LSTM 模型輸入長(zhǎng)度選擇技巧:提升序列建模效能的關(guān)鍵? 在循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)家族中,長(zhǎng)短期記憶網(wǎng)絡(luò)(LSTM)憑借其解決長(zhǎng)序列 ...
2025-07-11CDA 數(shù)據(jù)分析師報(bào)考條件詳解與準(zhǔn)備指南? ? 在數(shù)據(jù)驅(qū)動(dòng)決策的時(shí)代浪潮下,CDA 數(shù)據(jù)分析師認(rèn)證愈發(fā)受到矚目,成為眾多有志投身數(shù) ...
2025-07-11數(shù)據(jù)透視表中兩列相乘合計(jì)的實(shí)用指南? 在數(shù)據(jù)分析的日常工作中,數(shù)據(jù)透視表憑借其強(qiáng)大的數(shù)據(jù)匯總和分析功能,成為了 Excel 用戶 ...
2025-07-11尊敬的考生: 您好! 我們誠(chéng)摯通知您,CDA Level I和 Level II考試大綱將于 2025年7月25日 實(shí)施重大更新。 此次更新旨在確保認(rèn) ...
2025-07-10BI 大數(shù)據(jù)分析師:連接數(shù)據(jù)與業(yè)務(wù)的價(jià)值轉(zhuǎn)化者? ? 在大數(shù)據(jù)與商業(yè)智能(Business Intelligence,簡(jiǎn)稱 BI)深度融合的時(shí)代,BI ...
2025-07-10SQL 在預(yù)測(cè)分析中的應(yīng)用:從數(shù)據(jù)查詢到趨勢(shì)預(yù)判? ? 在數(shù)據(jù)驅(qū)動(dòng)決策的時(shí)代,預(yù)測(cè)分析作為挖掘數(shù)據(jù)潛在價(jià)值的核心手段,正被廣泛 ...
2025-07-10數(shù)據(jù)查詢結(jié)束后:分析師的收尾工作與價(jià)值深化? ? 在數(shù)據(jù)分析的全流程中,“query end”(查詢結(jié)束)并非工作的終點(diǎn),而是將數(shù) ...
2025-07-10CDA 數(shù)據(jù)分析師考試:從報(bào)考到取證的全攻略? 在數(shù)字經(jīng)濟(jì)蓬勃發(fā)展的今天,數(shù)據(jù)分析師已成為各行業(yè)爭(zhēng)搶的核心人才,而 CDA(Certi ...
2025-07-09【CDA干貨】單樣本趨勢(shì)性檢驗(yàn):捕捉數(shù)據(jù)背后的時(shí)間軌跡? 在數(shù)據(jù)分析的版圖中,單樣本趨勢(shì)性檢驗(yàn)如同一位耐心的偵探,專注于從單 ...
2025-07-09year_month數(shù)據(jù)類型:時(shí)間維度的精準(zhǔn)切片? ? 在數(shù)據(jù)的世界里,時(shí)間是最不可或缺的維度之一,而year_month數(shù)據(jù)類型就像一把精準(zhǔn) ...
2025-07-09CDA 備考干貨:Python 在數(shù)據(jù)分析中的核心應(yīng)用與實(shí)戰(zhàn)技巧? ? 在 CDA 數(shù)據(jù)分析師認(rèn)證考試中,Python 作為數(shù)據(jù)處理與分析的核心 ...
2025-07-08SPSS 中的 Mann-Kendall 檢驗(yàn):數(shù)據(jù)趨勢(shì)與突變分析的有力工具? ? ? 在數(shù)據(jù)分析的廣袤領(lǐng)域中,準(zhǔn)確捕捉數(shù)據(jù)的趨勢(shì)變化以及識(shí)別 ...
2025-07-08備戰(zhàn) CDA 數(shù)據(jù)分析師考試:需要多久?如何規(guī)劃? CDA(Certified Data Analyst)數(shù)據(jù)分析師認(rèn)證作為國(guó)內(nèi)權(quán)威的數(shù)據(jù)分析能力認(rèn)證 ...
2025-07-08LSTM 輸出不確定的成因、影響與應(yīng)對(duì)策略? 長(zhǎng)短期記憶網(wǎng)絡(luò)(LSTM)作為循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)的一種變體,憑借獨(dú)特的門控機(jī)制,在 ...
2025-07-07統(tǒng)計(jì)學(xué)方法在市場(chǎng)調(diào)研數(shù)據(jù)中的深度應(yīng)用? 市場(chǎng)調(diào)研是企業(yè)洞察市場(chǎng)動(dòng)態(tài)、了解消費(fèi)者需求的重要途徑,而統(tǒng)計(jì)學(xué)方法則是市場(chǎng)調(diào)研數(shù) ...
2025-07-07CDA數(shù)據(jù)分析師證書考試全攻略? 在數(shù)字化浪潮席卷全球的當(dāng)下,數(shù)據(jù)已成為企業(yè)決策、行業(yè)發(fā)展的核心驅(qū)動(dòng)力,數(shù)據(jù)分析師也因此成為 ...
2025-07-07剖析 CDA 數(shù)據(jù)分析師考試題型:解鎖高效備考與答題策略? CDA(Certified Data Analyst)數(shù)據(jù)分析師考試作為衡量數(shù)據(jù)專業(yè)能力的 ...
2025-07-04SQL Server 字符串截取轉(zhuǎn)日期:解鎖數(shù)據(jù)處理的關(guān)鍵技能? 在數(shù)據(jù)處理與分析工作中,數(shù)據(jù)格式的規(guī)范性是保證后續(xù)分析準(zhǔn)確性的基礎(chǔ) ...
2025-07-04CDA 數(shù)據(jù)分析師視角:從數(shù)據(jù)迷霧中探尋商業(yè)真相? 在數(shù)字化浪潮席卷全球的今天,數(shù)據(jù)已成為企業(yè)決策的核心驅(qū)動(dòng)力,CDA(Certifie ...
2025-07-04CDA 數(shù)據(jù)分析師:開(kāi)啟數(shù)據(jù)職業(yè)發(fā)展新征程? ? 在數(shù)據(jù)成為核心生產(chǎn)要素的今天,數(shù)據(jù)分析師的職業(yè)價(jià)值愈發(fā)凸顯。CDA(Certified D ...
2025-07-03