11 享元模式

2021-09-29 16:48:09 字數 3347 閱讀 7831

一、享元模式

享元設計模式通過為相似物件引入資料共享來最小化記憶體使用,提公升效能。

享元模式定義如下:使用共享物件支援大量細粒度物件。大量細粒度的物件的支援共享,可能會涉及這些物件的兩類資訊:內部狀態資訊和外部狀態資訊。內部狀態資訊就是可共享出來的資訊,它們儲存在享元物件內部,不會隨著特定環境的改變而改變;外部狀態資訊就不可共享的資訊了。享元模式中只包含內部狀態資訊,而不應該包含外部狀態資訊。這點在設計業務架構時,應該有所考慮。下面是乙個網上咖啡選購平台的示例:

咖啡類:

class

coffee

: name =

'' price =

0def

__init__

(self,name)

: self.name = name

self.price =

len(name)

# 在實際業務中,咖啡**應該是由配置表進行配置,或者呼叫介面獲取等方式得到,此處為說明享元模式,將咖啡**定為名稱長度,只是一種簡化

defshow

(self)

:print

"coffee name:%s price:%s"

%(self.name,self.price)

顧客類:

class

customer

: name=

""def

__init__

(self,name)

: self.name=name

deforder

(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 =

defgetcoffee

(self, name)

:if self.coffee_dict.has_key(name)

==false

: self.coffee_dict[name]

= coffee(name)

return self.coffee_dict[name]

defgetcoffeecount

(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

deforder

(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)

))c2_mocha=customer_2.order(

"mocha"

) c2_mocha.show(

) ))

print

"num of coffee instance:%s"

%coffee_factory.getcoffeecount(

)

列印如下:

10b client ordered a cup of coffee:mocha

coffee name:mocha price:510

num of coffee instance:

2根據結果可以得知,該模式下三個使用者點了兩種咖啡,最終的咖啡例項為2,而不是3。

二、享元模式的優點和使用場景

優點:

1、減少重複物件,大大節約了系統資源。

使用場景

1、系統中存在大量的相似物件時,可以選擇享元模式提高資源利用率。咖啡訂購平台比較小,若假設乙個電商平台,每個買家和賣家建立起買賣關係後,買家物件和賣家物件都是占用資源的。如果乙個賣家同時與多個買家建立起買賣關係呢?此時享元模式的優勢就體現出來了;

2、需要緩衝池的場景中,可以使用享元模式。如程序池,執行緒池等技術,就可以使用享元模式(事實上,很多的池技術中已經使得了享元模式)。

三、享元模式的缺點

1、享元模式雖然節約了系統資源,但同時也提高了系統的複雜性,尤其當遇到外部狀態和內部狀態混在一起時,需要先將其進行分離,才可以使用享元模式。否則,會引起邏輯混亂或業務風險;

2、享元模式中需要額外注意執行緒安全問題。

(11)享元模式

享元模式用於減少建立物件的數量,以減少記憶體占用和提高效能。享元模式嘗試重用現有的同類物件,如果未找到匹配的物件,則建立新物件。享元模式用得比較多的是池化技術,如常量池,執行緒池,連線池等等。import j a.util.hashmap import j a.util.map 享元模式 publi...

設計模式 11 享元模式

舉個圍棋的例子,圍棋的棋盤共有361格,即可放361個棋子。現在要實現乙個圍棋程式,該怎麼辦呢?首先要考慮的是棋子棋盤的實現,可以定義乙個棋子的類,成員變數包括棋子的顏色 形狀 位置等資訊,另外再定義乙個棋盤的類,成員變數中有個容器,用於存放棋子的物件。下面給出 表示 棋子的定義,當然棋子的屬性除了...

設計模式 11 享元模式 Flyweight

轉 問題 在物件導向系統的設計何實現中,建立物件是最為常見的操作。這裡面就有乙個問題 如果乙個應用程式使用了太多的物件,就會造成很大的儲存開銷。特別是對於大量輕量級 細 粒度 的物件,比如在文件編輯器的設計過程中,我們如果為沒有字母建立乙個物件的話,系統可能會因為大量的物件而造成儲存開銷的浪費。例如...