摘要:還有一個(gè)工廠類。工廠類有一個(gè)方法名有兩個(gè)輸入?yún)?shù),名字和性別。用戶使用工廠類,通過調(diào)用方法。抽象工廠模式提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口,而無須指定它們具體的類。
概念
工廠模式:工廠模式就是不管如何實(shí)現(xiàn)的,只需要調(diào)用抽象話的接口就可以創(chuàng)建出特定類型的實(shí)例對(duì)象
簡(jiǎn)單工廠模式:
eg:一個(gè)例子更能很好的理解以上的內(nèi)容:
我們有一個(gè)基類Person ,包涵獲取名字,性別的方法 。有兩個(gè)子類male 和female,可以打招呼。還有一個(gè)工廠類。
工廠類有一個(gè)方法名getPerson有兩個(gè)輸入?yún)?shù),名字和性別。
用戶使用工廠類,通過調(diào)用getPerson方法。
在程序運(yùn)行期間,用戶傳遞性別給工廠,工廠創(chuàng)建一個(gè)與性別有關(guān)的對(duì)象。因此工廠類在運(yùn)行期,決定了哪個(gè)對(duì)象應(yīng)該被創(chuàng)建。
class Person:
def __init__(self): self.name = None self.gender = None def getName(self): return self.name def getGender(self): return self.gender
class Male(Person):
def __init__(self, name): print "Hello Mr." + name
class Female(Person):
def __init__(self, name): print "Hello Miss." + name
class Factory:
def getPerson(self, name, gender): if gender == ‘M": return Male(name) if gender == "F": return Female(name)
if name == "__main__":
factory = Factory() person = factory.getPerson("Chetan", "M")
抽象工廠模式:
提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口,而無須指定它們具體的類。
class Burger():
""" 漢堡 """ name="" price=0.0 type="BURGER" def getPrice(self): return self.price def setPrice(self,price): self.price=price def getName(self): return self.name
class CheeseBurger(Burger):
def __init__(self): self.name="cheese burger" self.price=10.0
class SpicyChickenBurger(Burger):
def __init__(self): self.name="spicy chicken burger" self.price=15.0
class Snack():
""" 小食類 """ name = "" price = 0.0 type = "SNACK" def getPrice(self): return self.price def setPrice(self, price): self.price = price def getName(self): return self.name
class Chips(Snack):
def __init__(self): self.name = "chips" self.price = 6.0
class ChickenWings(Snack):
def __init__(self): self.name = "chicken wings" self.price = 12.0
class Beverage():
""" 飲料 """ name = "" price = 0.0 type = "BEVERAGE" def getPrice(self): return self.price def setPrice(self, price): self.price = price def getName(self): return self.name
class Coke(Beverage):
def __init__(self): self.name = "coke" self.price = 4.0
class Milk(Beverage):
def __init__(self): self.name = "milk" self.price = 5.0以上的Burger,Snack,Beverage,都可以認(rèn)為是該快餐店的產(chǎn)品,由于只提供了抽象方法,我們把它們叫抽象產(chǎn)品類,而cheese burger等6個(gè)由抽象產(chǎn)品類衍生出的子類,叫作具體產(chǎn)品類。
class FoodFactory():
""" 抽象工廠foodFactory為抽象的工廠類,而burgerFactory,snackFactory,beverageFactory為具體的工廠類。 """ type="" def createFood(self,foodClass): print(self.type," factory produce a instance.") foodIns=foodClass() return foodIns
class BurgerFactory(foodFactory):
def __init__(self): self.type="BURGER"
class SnackFactory(foodFactory):
def __init__(self): self.type="SNACK"
class BeverageFactory(foodFactory):
def __init__(self): self.type="BEVERAGE"
if __name__=="__main__":
burger_factory=burgerFactory() snack_factory=snackFactory() beverage_factory=beverageFactory() cheese_burger=burger_factory.createFood(cheeseBurger) print(cheese_burger.getName(),cheese_burger.getPrice()) chicken_wings=snack_factory.createFood(chickenWings) print(chicken_wings.getName(),chicken_wings.getPrice()) coke_drink=beverage_factory.createFood(coke) print(coke_drink.getName(),coke_drink.getPrice())
工廠模式優(yōu)點(diǎn)
工廠方法用來創(chuàng)建客戶所需要的產(chǎn)品,同時(shí)還向客戶隱藏了哪種具體產(chǎn)品類將被實(shí)例化這一細(xì)節(jié) 能夠讓工廠自主確定創(chuàng)建何種產(chǎn)品對(duì)象,而如何創(chuàng)建這個(gè)對(duì)象的細(xì)節(jié)則完全封裝在具體工廠內(nèi)部 在系統(tǒng)中加入新產(chǎn)品時(shí),完全符合開閉原則
工廠模式缺點(diǎn)
系統(tǒng)中類的個(gè)數(shù)將成對(duì)增加,在一定程度上增加了系統(tǒng)的復(fù)雜度,會(huì)給系統(tǒng)帶來一些額外的開銷 增加了系統(tǒng)的抽象性和理解難度
工廠模式適用環(huán)境
客戶端不知道它所需要的對(duì)象的類(客戶端不需要知道具體產(chǎn)品類的類名,只需要知道所對(duì)應(yīng)的工廠即可,具體產(chǎn)品對(duì)象由具體工廠類創(chuàng)建) 抽象工廠類通過其子類來指定創(chuàng)建哪個(gè)對(duì)象
抽象工廠模式:
模式優(yōu)點(diǎn)
隔離了具體類的生成,使得客戶端并不需要知道什么被創(chuàng)建 當(dāng)一個(gè)產(chǎn)品族中的多個(gè)對(duì)象被設(shè)計(jì)成一起工作時(shí),它能夠保證客戶端始終只使用同一個(gè)產(chǎn)品族中的對(duì)象 增加新的產(chǎn)品族很方便,無須修改已有系統(tǒng),符合開閉原則
模式缺點(diǎn)
增加新的產(chǎn)品等級(jí)結(jié)構(gòu)麻煩,需要對(duì)原有系統(tǒng)進(jìn)行較大的修改,甚至需要修改抽象層代碼,這顯然會(huì)帶來較大的不便,違背了開閉原則
模式適用環(huán)境
一個(gè)系統(tǒng)不應(yīng)當(dāng)依賴于產(chǎn)品類實(shí)例如何被創(chuàng)建、組合和表達(dá)的細(xì)節(jié) 系統(tǒng)中有多于一個(gè)的產(chǎn)品族,但每次只使用其中某一產(chǎn)品族 屬于同一個(gè)產(chǎn)品族的產(chǎn)品將在一起使用,這一約束必須在系統(tǒng)的設(shè)計(jì)中體現(xiàn)出來 產(chǎn)品等級(jí)結(jié)構(gòu)穩(wěn)定,設(shè)計(jì)完成之后,不會(huì)向系統(tǒng)中增加新的產(chǎn)品等級(jí)結(jié)構(gòu)或者刪除已有的產(chǎn)品等級(jí)結(jié)構(gòu)
單例模式
單例模式(Singleton Pattern)是一種常用的軟件設(shè)計(jì)模式,該模式的主要目的是確保某一個(gè)類只有一個(gè)實(shí)例存在。當(dāng)你希望在整個(gè)系統(tǒng)中,某個(gè)類只能出現(xiàn)一個(gè)實(shí)例時(shí),單例對(duì)象就能派上用場(chǎng)。 eg:系統(tǒng)中的打印機(jī)
實(shí)現(xiàn)方式:
使用模塊:
在mysingleton.py模塊文件中:(因?yàn)槟K在第一次導(dǎo)入時(shí)生成了.pyc文件,下次會(huì)直接從這個(gè)里面加載,不需要重新生成)
class Singleton:(object):
def foo(self): pass
singleton = Singeton()
在其他文件中調(diào)用:
from mysingleton import singleton
使用裝飾器:
def Singleton(cls):
_instance = {} def _singleton(*args, **kargs):此處是核心代碼
if cls not in _instance: _instance[cls] = cls(*args, **kargs) return _instance[cls]此處是核心代碼
return _singleton
@Singleton
class A(object):
a = 1 def __init__(self, x=0): self.x = x
a1 = A(2)
a2 = A(3)
print(id(a1))
print(id(a2))
使用類
import time
import threading
class Singleton(object):
_instance_lock = threading.Lock() def __init__(self): time.sleep(1) @classmethod def instance(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): with Singleton._instance_lock: if not hasattr(Singleton, "_instance"): Singleton._instance = Singleton(*args, **kwargs) return Singleton._instance
def task(arg):
obj = Singleton.instance() print(obj)
for i in range(10):
t = threading.Thread(target=task,args=[i,]) t.start()
time.sleep(20)
obj = Singleton.instance()
print(obj)
基于__new__方法創(chuàng)建單例
import threading
class Singleton(object):
_instance_lock = threading.Lock() def __init__(self): pass def __new__(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): with Singleton._instance_lock: if not hasattr(Singleton, "_instance"): Singleton._instance = object.__new__(cls) return Singleton._instance
obj1 = Singleton()
obj2 = Singleton()
print(obj1,obj2)
def task(arg):
obj = Singleton() print(obj)
for i in range(10):
t = threading.Thread(target=task,args=[i,]) t.start()
基于metaclass方式來實(shí)現(xiàn)
import threading
class SingletonType(type):
_instance_lock = threading.Lock() def __call__(cls, *args, **kwargs): if not hasattr(cls, "_instance"): with SingletonType._instance_lock: if not hasattr(cls, "_instance"): cls._instance = super(SingletonType,cls).__call__(*args, **kwargs) return cls._instance
class Foo(metaclass=SingletonType):
def __init__(self,name): self.name = name
obj1 = Foo("name")
obj2 = Foo("name")
print(obj1,obj2)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/43679.html
摘要:使用的好處知乎的回答不用自己組裝,拿來就用。統(tǒng)一配置,便于修改。 前言 只有光頭才能變強(qiáng) 回顧前面: 給女朋友講解什么是代理模式 包裝模式就是這么簡(jiǎn)單啦 單例模式你會(huì)幾種寫法? 工廠模式理解了沒有? 在刷Spring書籍的時(shí)候花了點(diǎn)時(shí)間去學(xué)習(xí)了單例模式和工廠模式,總的來說還是非常值得的! 本來想的是刷完《Spring 實(shí)戰(zhàn) (第4版)》和《精通Spring4.x 企業(yè)應(yīng)用開發(fā)實(shí)戰(zhàn)》...
摘要:?jiǎn)卫J疥P(guān)注的重點(diǎn)私有構(gòu)造器線程安全延遲加載序列化和反序列化安全反射攻擊安全相關(guān)設(shè)計(jì)模式單例模式和工廠模式工廠類可以設(shè)計(jì)成單例模式。 0x01.定義與類型 定義:保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)全局訪問點(diǎn) 類型:創(chuàng)建型 UML showImg(https://segmentfault.com/img/bVbtDJ2?w=402&h=268); 單例模式的基本要素 私有的構(gòu)造方...
摘要:?jiǎn)卫J礁攀鰡卫J绞且环N對(duì)象創(chuàng)建模式,用于產(chǎn)生一個(gè)類的具體事例。所以解決了線程安全問題參考失效原因和解決方案中單例模式的缺陷及單例的正確寫法懶漢式靜態(tài)內(nèi)部類私有構(gòu)造器獲取單例的方法靜態(tài)內(nèi)部類持有單例作為靜態(tài)屬性。 單例模式概述 單例模式是一種對(duì)象創(chuàng)建模式,用于產(chǎn)生一個(gè)類的具體事例。使用單例模式可以確保整個(gè)系統(tǒng)中單例類只產(chǎn)生一個(gè)實(shí)例。有下面兩大好處: 對(duì)于頻繁創(chuàng)建的對(duì)象,節(jié)省初第一...
摘要:面試官要不你來手寫下單例模式唄候選者單例模式一般會(huì)有好幾種寫法候選者餓漢式簡(jiǎn)單懶漢式在方法聲明時(shí)加鎖雙重檢驗(yàn)加鎖進(jìn)階懶漢式靜態(tài)內(nèi)部類優(yōu)雅懶漢式枚舉候選者所謂餓漢式指的就是還沒被用到,就直接初始化了對(duì)象。面試官:我看你的簡(jiǎn)歷寫著熟悉常見的設(shè)計(jì)模式,要不你來簡(jiǎn)單聊聊你熟悉哪幾個(gè)吧?候選者:常見的工廠模式、代理模式、模板方法模式、責(zé)任鏈模式、單例模式、包裝設(shè)計(jì)模式、策略模式等都是有所了解的候選者:...
摘要:抽象工廠模式多個(gè)抽象產(chǎn)品類,個(gè)抽象產(chǎn)品類可以派生出多個(gè)具體產(chǎn)品類。用了工廠方法模式,你替換生成鍵盤的工廠方法,就可以把鍵盤從羅技換到微軟。好處避免頻繁創(chuàng)建對(duì)象,節(jié)省系統(tǒng)開銷,減輕壓力。 總體分為3大類:創(chuàng)建型模式 (5種):工廠方法、抽象工廠、單例、建造者、原型結(jié)構(gòu)型模式(7種):適配器、裝飾器、代理、外觀、橋接、組合、享元行為型模式(11種):策略、模板方法、觀察者、迭代子、責(zé)任鏈、...
閱讀 3165·2023-04-26 02:33
閱讀 3117·2023-04-25 21:33
閱讀 921·2021-09-02 09:56
閱讀 2938·2019-08-30 15:44
閱讀 2471·2019-08-30 13:15
閱讀 1046·2019-08-30 13:04
閱讀 1647·2019-08-29 15:09
閱讀 3980·2019-08-26 18:26