對享元模式的進(jìn)一步思考

從各種資料上我們知道享元模式的特點有:

1.對象是細(xì)粒度的, 比如字符串(python的短字符串對象就是這樣設(shè)計的), 數(shù)字類別這樣, 而不是{attr1, attr2, attr3 ....}這樣的

2.內(nèi)部狀態(tài)是穩(wěn)定的, 數(shù)量不多, 經(jīng)常重復(fù), 比如黑白棋的黑色子與白色子

3.外部狀態(tài)都不一樣, 棋子的位置.

然后享元模式的核心就在于工廠方法.每次被請求創(chuàng)建對象的時候,通過判斷池子里面有沒有來決定是否產(chǎn)生新的對象,進(jìn)而達(dá)到節(jié)約內(nèi)存的目的.

網(wǎng)上的很多資料介紹到這里也就結(jié)束了, 但是這樣留給我這樣的初級讀者的卻是一個極大的錯誤認(rèn)識---那就是內(nèi)存是大量的節(jié)約. 為什么這樣說呢, 就拿剛才的黑白棋的例子來說, 如果棋盤上有100個棋子, 我們認(rèn)為只產(chǎn)生了2個棋子對象(黑子和白子), 然后位置通過參數(shù)傳遞. 這樣內(nèi)存對象的壓縮率就達(dá)到了98%.

但是學(xué)過信息論的同學(xué)都知道, 就算使用各種神奇算法來編碼壓縮也逃不過香農(nóng)定律的極限.然而通過上面的直覺估算,反而是信息越多,壓縮比越高,比如10000000個棋子那么幾乎是100%的壓縮比了. 造成這個結(jié)果的原因就是我們一直在關(guān)注共享內(nèi)部狀態(tài),而忽視了外部狀態(tài)的管理.

我就以一款以前玩過的游戲--三國志來說:

故事設(shè)定---一個中級將領(lǐng)可以帶領(lǐng)100個純種兵員, 要么全是步兵, 或者全是騎兵, 或者全是象兵.在對打開始時(初始化), 100個兵出現(xiàn)在10*10的方陣中, 打的過程中還有可能死掉. 所以我們就用享元模式表示做這個戰(zhàn)斗過程中士兵對象.

大一剛學(xué)編程的我是這樣寫:

class Soldier{

? ? private type; ? //infantry

? ? private cor_x;

? ? private col_y;

? ? private is_alive;

}

我們假設(shè)每個屬性都是一個字節(jié),那么100個士兵就需要400 bytes的存儲.

a.按照我最初對享元模式的理解,那么壓縮比是99%

b.按照圍棋設(shè)計方案,我們把位置和死活剝離出來

class Soldier{

? ? private type; ?//infantry

? ? public void display( new Is_alive_and_position oooo);

}

class Is_alive_and_position{

? ? private cor_x;

? ? private col_y;

? ? private is_alive;

}

這樣的話,100個士兵就有1個Soldier對象和100個Is_alive_and_position對象,占用內(nèi)存是:

1*1 + 100*3 = 301, 壓縮比是25%

c.我們把種類和死活作為基礎(chǔ)共享類,然后位置對象剝離處理:

class Soldier{

? ? private type; ?//infantry

? ? private is_alive;

? ? public void display( new Position oooo);

}

class Position{

? private cor_x;

? private col_y;

}

占用內(nèi)存:2 * 2 + 100*2 = 204, 壓縮比是50%

d.我們進(jìn)一步剝離,把橫坐標(biāo)也作為基礎(chǔ)類的屬性, 因為只有1~10:

class Soldier{

? ? private type; ?//infantry

? ? private is_alive;

? ? private cor_x;

? ? public void display( new Position_y oooo);

}

class Position_y{

? ? private col_y;

}

這時,活的基礎(chǔ)士兵有10個,死的也有10個,共享類有20個. 在縱向的位置類有100個,所以

內(nèi)存:20*3 + 100*1=160, 那么壓縮比是60%

通過上面的對象壓縮比來看: 99%> 60% > 50% > 25%

? ? 第一個是騙人的,我們不管,?

? ? 最后一個節(jié)約不多,但是設(shè)計簡單,內(nèi)部狀態(tài)只有一個,共享對象也只能有一個

? ? 60%節(jié)約最多,但是共享類設(shè)計稍微復(fù)雜,而且共享對象也有20個

以上的分析是不考慮程序執(zhí)行耗時, 真實內(nèi)存狀態(tài)的. 只是建立一個模型來分析. 享元模式的重點不是享元工廠的設(shè)計,而是結(jié)合程序環(huán)境, 內(nèi)存節(jié)約度, 程序執(zhí)行效率, 類和對象管理復(fù)雜度來設(shè)計享元類和外部類. 這就好比在我們使用react或者vue.js時,核心的虛擬DOM樹并沒有減少必要的真實DOM操作,只是優(yōu)化的執(zhí)行過程.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末艺晴,一起剝皮案震驚了整個濱河市屎暇,隨后出現(xiàn)的幾起案子俭令,更是在濱河造成了極大的恐慌那先,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件却音,死亡現(xiàn)場離奇詭異改抡,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)系瓢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門阿纤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人夷陋,你說我怎么就攤上這事欠拾。” “怎么了骗绕?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵藐窄,是天一觀的道長。 經(jīng)常有香客問我酬土,道長荆忍,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任撤缴,我火速辦了婚禮刹枉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘屈呕。我一直安慰自己微宝,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布虎眨。 她就那樣靜靜地躺著蟋软,像睡著了一般。 火紅的嫁衣襯著肌膚如雪专甩。 梳的紋絲不亂的頭發(fā)上钟鸵,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機(jī)與錄音涤躲,去河邊找鬼棺耍。 笑死,一個胖子當(dāng)著我的面吹牛种樱,可吹牛的內(nèi)容都是我干的蒙袍。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼嫩挤,長吁一口氣:“原來是場噩夢啊……” “哼害幅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起岂昭,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤以现,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體邑遏,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡佣赖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了记盒。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片憎蛤。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖纪吮,靈堂內(nèi)的尸體忽然破棺而出俩檬,到底是詐尸還是另有隱情,我是刑警寧澤碾盟,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布棚辽,位于F島的核電站,受9級特大地震影響冰肴,放射性物質(zhì)發(fā)生泄漏晚胡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一嚼沿、第九天 我趴在偏房一處隱蔽的房頂上張望估盘。 院中可真熱鬧,春花似錦骡尽、人聲如沸遣妥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽箫踩。三九已至,卻和暖如春谭贪,著一層夾襖步出監(jiān)牢的瞬間境钟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工俭识, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留慨削,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓套媚,卻偏偏與公主長得像缚态,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子堤瘤,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法玫芦,類相關(guān)的語法,內(nèi)部類的語法本辐,繼承相關(guān)的語法桥帆,異常的語法医增,線程的語...
    子非魚_t_閱讀 31,625評論 18 399
  • 1 場景問題# 1.1 加入權(quán)限控制## 考慮這樣一個問題,給系統(tǒng)加入權(quán)限控制老虫,這基本上是所有的應(yīng)用系統(tǒng)都有的功能...
    七寸知架構(gòu)閱讀 2,490評論 1 57
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理调窍,服務(wù)發(fā)現(xiàn),斷路器张遭,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,101評論 25 707
  • 朋友聊天,說自己兒子家里刀和劍得有五六十把地梨,但每次出去看見菊卷,還要,而且專找貴的宝剖、特別的要洁闰,不給就撒潑,反正最后還得...
    芥子齊凱閱讀 143評論 0 0