設計模式之享元模式
(flyweight)
何謂享元
首先我們解釋一下什麼是享元?
這裡所說的享元出自大名鼎鼎的設計模式一書,英文
flyweight
,中文由誰翻譯成「享元」一詞已不可考,但不得不說,這個翻譯實在是精彩;望文即可生意,比起洋鬼子的
flyweight
高明太多。這不免讓我等程式設計師被洋鬼子壓倒在頭上多年終於可以聊以**(也就是
yy),雖然我不如你,但我們的老祖宗可比你們的老祖宗要強多了
– 我們的老祖宗確實很厲害,搞得我們除了老祖宗的東西也確實沒啥能拿出手的,大凡老子是英雄,兒子基本上都是狗熊。這真是悲哀
扯遠了,我們繼續享元;那何為享元,顧名思義,共享的單元嘛。例項a和
b都包含指向同乙個例項
c的索引,而不是直接包含c,
c就是享元;資料結構描述如下
struct c stc;
struct a sta = ;
struct b stb = ;
享元的應用
可以說,無論你有沒有意識到,**中享元實際上無處不在。遠的不說了,就是設計模式中的舉例,文件中文字格式的儲存,我們每天都用到,誰不用
office
軟體?如果說這個還是有些遙遠,畢竟不是自己設計的部分,那我們再看個例子;如果要儲存乙個學生資訊,包括學號和畢業學校名稱,有人會這樣設計這個資料結構嗎?
struct student ;
大部分情況來說,我們都不會這樣操作,這確實很浪費儲存空間;雖然現在電子產品越來越便宜,但我們也不能這樣敗家。我們可以這樣
struct college ;
struct student ;
這樣效果比較好一些
高階篇如果享元只是像我舉的例子那樣簡單,享元也就不能稱之為享元了;我們再仔細想想文件處理的例子,每個字元包括大小,字型
...,理論上應該定義成
struct char_formated ;
struct file ;
應用享元模式,定義成這樣也就差不多了
struct format_template ;
struct char_formated ;
當然,設計模式裡面玩的更狠一些,乾脆搞成這樣
struct formated_char ;
struct char_formated ;
有人會問這個問題嗎?
- 從表面上看,儲存空間不是耗費更多了嗎?至少多了
short
的空間吧。我看是沒有人會問了
所以這才是享元的精髓,把一些私有的資訊公共出來,以達到共享的效果;
文件當然是享元的乙個完美應用,但平常的**中有很多的實際的例子,只不過大家沒有多想,或者沒有在意
舉例:公司的應屆生招聘資訊記錄
struct student ;
這個資料結構定義沒有任何問題;相信碰到這種情況,大部分人隨手也就這樣做了;但實際上如果仔細考慮,完全可以使用享元:理論上同一屆的應屆生年齡相差不大(
3歲差不多了吧),入學時間和畢業時間應該都相同,性別,婚否每個
2,那一共有多少種情況呢?3乘
2再乘2 = 12
所以我們實際上可以這樣考慮下面的設計
struct template ;
struct student ;
從這裡看到的資料,大約會節約
12/20 = 60%
的空間(當然實際上應該是沒有的,因為學生還有很多其它的資訊);但這個資料也足夠振奮人心的了
但也由此可見,享元並不那麼直觀,我們需要細心觀察和總結;
遺留了一些問題:
1 uscollegeindex
可以抽取到享元中嗎?
2 什麼時候需要考慮享元?
3 什麼樣的資訊適合抽取出來作為享元?
小結享元是一種設計模式:並不針對面對物件,在
c語言,資料庫等等領域都有重要的價值;
享元更是一種思路,可共享的才是最好的
– 這無疑是面對物件的根本要義;在所有的業務領域也不失為乙個努力的方向
同時享元還揭示了乙個真理:不完美就是一種完美,它用乙個不完美的手法達到了完美的效果(感覺有點像易經中陰中有陽,陽中有陰,呵呵);如果你仔細觀察,生活中這種例子數不勝數。
享元如此精彩,但又如此朦朧;這不得不要求我們睜大雙眼,每日三省**:這裡可以享元嗎?
設計模式之享元模式
1 享元模式運用共享技術有效地支援大量細粒度的物件。uml圖如下 2 思考 flyweight根據客戶需求返回已經生成好的物件,但一定要事先生成物件例項嗎?答 實際上是不一定需要的,完全可以初始化的時候什麼也不做,到需要的時候,再去判斷物件是否為null來決定是否例項化。3 思考 為什麼要有unsh...
設計模式之 享元模式
享元模式英文稱為 flyweight pattern 又譯為羽量級模式或者蠅量級模式。享元模式的定義為 採用乙個共享類來避免大量擁有相同內容的 小類 的開銷。這種開銷中最常見 直觀的影響就是增加了記憶體的損耗。享元模式以共享的方式高效的支援大量的細粒度物件,減少其帶來的開銷。在名字和定義中都體現出了...
設計模式之享元模式
享元模式運用共享技術有效地支援大量細粒度的物件。如果乙個應用程式使用了大量的物件,而大量的這些物件造成了很大的儲存開銷時應該考慮使用。物件的大多數狀態可以是外部狀態,如果刪除物件的外部狀態,那麼可以用相對較少的共享物件取代很多組物件,此時也可以考慮用享元模式。享元模式uml圖如下 如下 使用者 cl...