設計模式之享元模式

2021-10-02 18:53:40 字數 4356 閱讀 2422

舉例分析1:

有客戶要求以新聞的形式發布

有客戶人要求以部落格的形式發布

舉例分析2:

在大學時代,估計每個人都去圖書館借過書。借書的流程很簡單,如果書架上有這本書直接拿走,到借閱機上借閱就好了,如果沒有,可以到圖書管理處去拿一本新書。對於整個圖書館來說,書其實就是共享的,但是我們會發現其實每次借的書都是那些破舊一點的書,而不是新書,這是因為學生太多了,如果我們每一次借書都拿出來一本新書,那整個圖書館估計會放不下,對於我們借書的流程和圖書共享的方式就是享元模式。

傳統方案解決**展現專案

直接複製貼上乙份,然後根據客戶不同要求,進行定製修改

給每個**租用乙個空間

方案設計示意圖

傳統方案解決**展現專案-問題分析

需要的**結構相似度很高,而且都不是高訪問量**,如果分成多個虛擬空間來

處理,相當於乙個相同**的例項物件很多,造成伺服器的資源浪費

對於**來說,由於是乙份例項,維護和擴充套件都更加容易

上面的解決思路就可以使用享元模式來解決

基本介紹

如果在乙個系統中存在多個相同的物件,那麼只需要共享乙份物件的拷貝,而不必為每一次使用都建立新的物件。目的是提高系統效能。

享元模式(flyweight pattern) 也叫蠅量模式: 運

用共享技術有效地支援大量細粒度的物件

常用於系統底層開發,解決系統的效能問題。像

資料庫連線池,裡面都是建立好的連線物件,在

這些連線物件中有我們需要的則直接拿來用,避

免重新建立,如果沒有我們需要的,則建立乙個

3)享元模式能夠解決重複物件的記憶體浪費的問題

當系統中有大量相似物件,需要緩衝池時。不需

總是建立新物件,可以從緩衝池裡拿。這樣可以

降低系統記憶體,同時提高效率

享元模式經典的應用場景就是池技術了,string常

量池、資料庫連線池、緩衝池等等都是享元模式

的應用,享元模式是池技術的重要實現方式

享元模式的原理類圖

1)享元工廠(llibrary):用於建立具體享元類,維護相同的享元物件。當請求物件已經存在時,直接返回物件,不存在時,在建立物件。在例子中的解釋就是圖書館,儲存了所有的書,當學生借書時,有就拿走,沒有買一本新書。這裡面其實是使用了單例模式的。

2)flyweight是抽象的享元角色, 他是產品的抽象類, 同時定義出物件的外部狀態和內部狀態(後面介紹) 的介面或實現

3)concreteflyweight是具體的享元角色,是具體的產品類,實現抽象角色定義相關業務

4)unsharedconcreteflyweight是不可共享的角色,一般不會出現在享元工廠

**編寫:

flyweight:定義需要共享的物件業務介面。享元類被建立出來總是為了實現某些特定的業務邏輯.

/**

* 定義抽象享元類(book)

** 抽象享元(book):定義需要共享的物件業務介面。享元類被建立出來總是為了實現某些特定的業務邏輯.

*/public

inte***ce

book

concreteflyweight:實現抽象享元類的介面,完成某一具體邏輯。

/**

* @author 孫一鳴 on 2020/2/13

* 具體享元(concretebook):實現抽象享元類的介面,完成某一具體邏輯。在這裡表示可以被借出。

* */

public

class

concretebook

implements

book

@override

public

void

borrow()

}

享元工廠(llibrary):圖書館,儲存了所有的書,當學生借書時,有就拿走,沒有買一本新書。

/**

* 享元工廠

* * @author 孫一鳴 on 2020/2/13

*/public

class

library

//圖書館外借圖書

public book libto

(string bookname)

else

return order;

}//圖書館書架上書的數量

public

intgetallbooks()

}

學生類:

/**

* @author 孫一鳴 on 2020/2/13

*/public

class

student

public

static

void

main

(string[

] args)

system.out.

println

("學生一共借了"

+books.

size()

);system.out.

println

("圖書館實際借出"

+library.

getallbooks()

);}}

結果截圖:

內部狀態和外部狀態

比如圍棋、五子棋、跳棋,它們都有大量的棋子物件,圍棋和五子棋只有黑白兩色,跳棋顏色多一

點,所以棋子顏色就是棋子的內部狀態;而各個棋子之間的差別就是位置的不同,當我們落子後,

落子顏色是定的,但位置是變化的,所以棋子座標就是棋子的外部狀態

享元模式提出了兩個要求:細粒度和共享物件。這裡就涉及到內部狀態和外部狀態

了,即將物件的資訊分為兩個部分:內部狀態和外部狀態

內部狀態指物件共享出來的資訊,儲存在享元物件內部且不會隨環境的改變而改變

外部狀態指物件得以依賴的乙個標記,是隨環境改變而改變的、不可共享的狀態。

舉個例子:圍棋理論上有361個空位可以放棋子,每盤棋都有可能有兩三百個棋子物件產生,因為記憶體空間有限,一台伺服器很難支援更多的玩家玩圍棋遊戲,如果用享元模式來處理棋子,那麼棋子物件就可以減少到只有兩個例項,這樣就很好的解決了物件的開銷問題

享元模式的注意事項和細節

在享元模式這樣理解,「享」就表示共享,「元」表示物件

系統中有大量物件,這些物件消耗大量記憶體,並且物件的狀態大部分可以外部化時,我們就可以考慮選用享元模式

唯一標識碼判斷,如果在記憶體中有,則返回這個唯一標識碼所標識的物件,用

hashmap/hashtable儲存

享元模式大大減少了物件的建立,降低了程式記憶體的占用,提高效率

享元模式提高了系統的複雜度。需要分離出內部狀態和外部狀態,而外部狀態具有固化特性,不應該隨著內部狀態的改變而改變,這是我們使用享元模式需要注意的地方.

使用享元模式時,注意劃分內部狀態和外部狀態,並且需要有乙個工廠類加以控制。

享元模式經典的應用場景是需要緩衝池的場景,比如 string常量池、資料庫連線池

享元模式的優點

(1)節省記憶體空間,對於可重複的物件只會被建立一次,物件比較多時,就會極大的節省空間。

(2)提高效率,由於建立物件的數量減少,所以對系統記憶體的需求也減小,使得速度更快,效率更高。

享元模式的缺點

其實對於享元類有內部狀態和外部狀態,其區分就是圖書館的書一部分可以外借(外部狀態),一部分不可外借(內部狀態),兩個狀態的劃分對於書籍管理來說優點複雜化了。

享元模式與單例模式的區別

(1)享元設計模式是乙個類有很多物件,而單例是乙個類僅乙個物件。

(2)享元模式是為了節約記憶體空間,提公升程式效能,而單例模式則主要是出於共享狀態的目的。

設計模式之享元模式

1 享元模式運用共享技術有效地支援大量細粒度的物件。uml圖如下 2 思考 flyweight根據客戶需求返回已經生成好的物件,但一定要事先生成物件例項嗎?答 實際上是不一定需要的,完全可以初始化的時候什麼也不做,到需要的時候,再去判斷物件是否為null來決定是否例項化。3 思考 為什麼要有unsh...

設計模式之 享元模式

享元模式英文稱為 flyweight pattern 又譯為羽量級模式或者蠅量級模式。享元模式的定義為 採用乙個共享類來避免大量擁有相同內容的 小類 的開銷。這種開銷中最常見 直觀的影響就是增加了記憶體的損耗。享元模式以共享的方式高效的支援大量的細粒度物件,減少其帶來的開銷。在名字和定義中都體現出了...

設計模式之享元模式

享元模式運用共享技術有效地支援大量細粒度的物件。如果乙個應用程式使用了大量的物件,而大量的這些物件造成了很大的儲存開銷時應該考慮使用。物件的大多數狀態可以是外部狀態,如果刪除物件的外部狀態,那麼可以用相對較少的共享物件取代很多組物件,此時也可以考慮用享元模式。享元模式uml圖如下 如下 使用者 cl...