10、Python與設計模式–享元模式
一、網上咖啡選購平臺
假設有一個網上咖啡選購平臺,客戶可以在該平臺上下訂單訂購咖啡,平臺會根據使用者位置進行線下配送。假設其咖啡物件構造如下:
class Coffee:
name = ``
price =0
def __init__(self,name):
self.name = name
self.price = len(name)#在實際業務中,咖啡價格應該是由配置表進行配置,或者呼叫介面獲取等方式得到,此處為說明享元模式,將咖啡價格定為名稱長度,只是一種簡化
def show(self):
print "Coffee Name:%s Price:%s"%(self.name,self.price)
其對應的顧客類如下:
class Customer:
name=""
def __init__(self,name):
self.name=name
def order(self,coffee_name):
print "%s ordered a cup of coffee:%s"%(self.name,coffee_name)
return Coffee(coffee_name)
按照一般的處理流程,使用者在網上預訂咖啡,其代表使用者的Customer類中生成一個Coffee類,直到交易流程結束。整個流程是沒有問題的。如果,隨著網站使用者越來越多,單位時間內購買咖啡的使用者也越來越多,併發量越來越大,對系統資源的消耗也會越來越大,極端情況下,會造成當機等嚴重後果。此時,高效利用資源,就顯得非常重要了。
簡單分析下業務流程,高併發下使用者數量增加,而該模型下,每個使用者點一杯咖啡,就會產生一個咖啡例項,如果一種咖啡在該時間內被很多使用者點過,那麼就會產生很多同樣咖啡的例項。避免重複例項的出現,是節約系統資源的一個突破口。類似於單例模式,我們這裡在咖啡例項化前,增加一個控制例項化的類:咖啡工廠。
class CoffeeFactory():
coffee_dict = {}
def getCoffee(self, name):
if self.coffee_dict.has_key(name) == False:
self.coffee_dict[name] = Coffee(name)
return self.coffee_dict[name]
def getCoffeeCount(self):
return len(self.coffee_dict)
咖啡工廠中,getCoffeeCount直接返回當前例項個數。Customer類可以重寫下,如下:
class Customer:
coffee_factory=""
name=""
def __init__(self,name,coffee_factory):
self.name=name
self.coffee_factory=coffee_factory
def order(self,coffee_name):
print "%s ordered a cup of coffee:%s"%(self.name,coffee_name)
return self.coffee_factory.getCoffee(coffee_name)
假設業務中短時間內有多人訂了咖啡,業務模擬如下:
if __name__=="__main__":
coffee_factory=CoffeeFactory()
customer_1=Customer("A Client",coffee_factory)
customer_2=Customer("B Client",coffee_factory)
customer_3=Customer("C Client",coffee_factory)
c1_capp=customer_1.order("cappuccino")
c1_capp.show()
c2_mocha=customer_2.order("mocha")
c2_mocha.show()
c3_capp=customer_3.order("cappuccino")
c3_capp.show()
print "Num of Coffee Instance:%s"%coffee_factory.getCoffeeCount()
列印如下:
A Client ordered a cup of coffee:cappuccino
Coffee Name:cappuccino Price:10
B Client ordered a cup of coffee:mocha
Coffee Name:mocha Price:5
C Client ordered a cup of coffee:cappuccino
Coffee Name:cappuccino Price:10
Num of Coffee Instance:2
根據結果可以得知,該模式下三個使用者點了兩種咖啡,最終的咖啡例項為2,而不是3。
二、享元模式
享元模式定義如下:使用共享物件支援大量細粒度物件。大量細粒度的物件的支援共享,可能會涉及這些物件的兩類資訊:內部狀態資訊和外部狀態資訊。內部狀態資訊就是可共享出來的資訊,它們儲存在享元物件內部,不會隨著特定環境的改變而改變;外部狀態資訊就不可共享的資訊了。享元模式中只包含內部狀態資訊,而不應該包含外部狀態資訊。這點在設計業務架構時,應該有所考慮。
三、享元模式的優點和使用場景
優點:
1、減少重複物件,大大節約了系統資源。
使用場景:
1、系統中存在大量的相似物件時,可以選擇享元模式提高資源利用率。咖啡訂購平臺比較小,若假設一個電商平臺,每個買家和賣家建立起買賣關係後,買家物件和賣家物件都是佔用資源的。如果一個賣家同時與多個買家建立起買賣關係呢?此時享元模式的優勢就體現出來了;
2、需要緩衝池的場景中,可以使用享元模式。如程式池,執行緒池等技術,就可以使用享元模式(事實上,很多的池技術中已經使得了享元模式)。
四、享元模式的缺點
1、享元模式雖然節約了系統資源,但同時也提高了系統的複雜性,尤其當遇到外部狀態和內部狀態混在一起時,需要先將其進行分離,才可以使用享元模式。否則,會引起邏輯混亂或業務風險;
2、享元模式中需要額外注意執行緒安全問題。
相關文章
- Python設計模式-享元模式Python設計模式
- 通俗 Python 設計模式——享元模式Python設計模式
- 設計模式----享元模式設計模式
- 設計模式-享元模式設計模式
- 設計模式【10】-- 順便看看享元模式設計模式
- 設計模式之享元模式設計模式
- javascript設計模式享元模式JavaScript設計模式
- 設計模式(十七):享元模式設計模式
- 設計模式系列13–享元模式設計模式
- 極簡設計模式-享元模式設計模式
- Java設計模式11——享元模式Java設計模式
- iOS設計模式 (四)享元模式iOS設計模式
- 軟體設計模式————(享元模式)設計模式
- C#設計模式(13)——享元模式C#設計模式
- Java設計模式之(十一)——享元模式Java設計模式
- 設計模式系列13--享元模式設計模式
- C#設計模式之享元模式C#設計模式
- 我學設計模式 之 享元模式設計模式
- Java學設計模式之享元模式Java設計模式
- Java設計模式(13):享元模式(蠅量模式)Java設計模式
- 《JavaScript設計模式與開發實踐》模式篇(9)—— 享元模式JavaScript設計模式
- 《設計模式四》觀察、組合、享元模式設計模式
- 設計模式 | 享元模式及典型應用設計模式
- 11.java設計模式之享元模式Java設計模式
- Java設計模式之七 —– 享元模式和代理模式Java設計模式
- 12.享元模式設計思想模式
- 每天一個設計模式之享元模式設計模式
- 軟體設計模式系列之十三——享元模式設計模式
- 設計模式--享元模式FlyWeight(結構型)設計模式
- C#設計模式系列:享元模式(Flyweight)C#設計模式
- 設計模式(十六)----結構型模式之代理享元模式設計模式
- 好程式設計師分享java設計模式之享元模式程式設計師Java設計模式
- 好程式設計師精講 java設計模式—享元模式程式設計師Java設計模式
- 物件池與享元模式物件模式
- 無廢話設計模式(9)結構型模式--享元模式設計模式
- Rust語言之GoF設計模式:Flyweight享元模式RustGo設計模式
- 設計模式之:享元模式FlyweightPattern的實現設計模式
- 享元模式模式