溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Flyweight享元模式怎么實現(xiàn)

發(fā)布時間:2022-03-25 10:46:58 來源:億速云 閱讀:135 作者:iii 欄目:web開發(fā)

今天小編給大家分享一下Flyweight享元模式怎么實現(xiàn)的相關(guān)知識點,內(nèi)容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

Flyweight(享元模式)

Flyweight(享元模式)屬于結(jié)構(gòu)型模式,是一種共享對象的設(shè)計模式。

意圖:運用共享技術(shù)有效地支持大量細粒度的對象。

舉例子

如果看不懂上面的意圖介紹,沒有關(guān)系,設(shè)計模式需要在日常工作里用起來,結(jié)合例子可以加深你的理解,下面我準備了三個例子,讓你體會什么場景下會用到這種設(shè)計模式。

富文本編輯器的字母對象

富文本編輯器在英文環(huán)境下,其中的文本由大量字母組成,為了便于做統(tǒng)一的格式化、計算等處理,需要將每個字母都存儲為對象,但這樣存儲的代價太大了。

已知英文字母一共 26 個,所以文檔中存在大量重復使用的字母,而每個字母除了位置信息外,其它信息都是相同且只讀的,那么有辦法降低富文本場景巨大的字母對象數(shù)量嗎?

網(wǎng)盤存儲

當我們上傳一部電影時,有時候幾十 GB 的內(nèi)容不到一秒就上傳完了,這是網(wǎng)盤提示你,“已采用極速技術(shù)秒傳”,你會不會心生疑惑,這么厲害的技術(shù)為什么不能每次都生效?

另外,網(wǎng)盤存儲時,同一部電影可能都會存放在不同用戶的不同文件夾中,而且電影文件又特別巨大,和富文本類似,電影文件也只有存放位置是不同的,而其余內(nèi)容都特別巨大且只讀,有什么辦法能優(yōu)化存儲呢?

大型多人游戲

玩多人游戲時,為了防止外掛,一般對象的創(chuàng)建與計算是在服務器完成的,那如何保證一個玩家拾取物品后,另一個玩家看到的物品會消失?

其實道理已經(jīng)不言而喻了,雖然在不同客戶端之間,游戲?qū)ο笫窍嗷オ毩⒌?,但在一局游戲中,所有玩家的對象在服務器是共享的?/p>

意圖解釋

“共享” 就是享元模式的精髓,將那些大量的,具有很多內(nèi)部狀態(tài)而外部狀態(tài)很少的對象進行共享,就是享元模式的使用方式。

意圖:運用共享技術(shù)有效地支持大量細粒度的對象。

共享技術(shù)可以理解為緩存,當一個對象創(chuàng)建后,再次訪問相同對象時,就不再創(chuàng)建新的對象了,而只有在訪問沒有被緩存過的對象時,才創(chuàng)建新對象,并立即緩存起來。

這樣做可以有效支持大量細粒度的對象,在富文本例子中,無數(shù)的字母就是大量細粒度對象,在網(wǎng)盤存儲中,電影文件就是大量細粒度對象,在大型多人游戲中,每局游戲內(nèi)存在大量細粒度對象。

這些細粒度對象都擁有相同的特征:

量特別大,這個很容易理解。

具有大量內(nèi)部狀態(tài),且不隨著客戶端的不同而改變。

富文本的字母,不因為展示到不同語句中而發(fā)生變化,變化的只有狀態(tài);電影文件,不因為放在不同用戶的文件夾中而對電影內(nèi)容產(chǎn)生變化,變化的只有屬于哪些用戶,放在哪些文件夾里;多人游戲中,同一把武器對象,不因為有多個人的電腦獨立運行而擁有更多的彈藥,變化的只有在哪些客戶端被訪問。

具有少量外部狀態(tài),甚至沒有外部狀態(tài)。在上面已經(jīng)解釋了,字母的位置、電影的位置、游戲?qū)ο蟮目蛻舳硕际峭獠繝顟B(tài),這些外部狀態(tài)相比于其內(nèi)部狀態(tài)來說,大小微乎其微,且方便分離存儲。

遇到這種情況,我們就可以將對象內(nèi)部狀態(tài)共享,外部狀態(tài)獨立存儲,從而節(jié)省大量空間。

尤其是對于網(wǎng)盤的場景,承諾給用戶 2 TB 的存儲空間,這個用戶看到其他人分享了 100 個電影,就點擊 “下載到我的網(wǎng)盤”,此時雖然占用了自己 1 TB 的網(wǎng)盤空間,但實際上網(wǎng)盤運營商并沒有增加 1 TB 的存儲空間,實際可能增加了 1kb 的存儲空間,記錄了存儲位置,這就是網(wǎng)盤雞賊的地方,并不占用空間的內(nèi)容,卻占用了用戶真金白銀購買的存儲空間。

當然,這就是享元模式的價值,對網(wǎng)盤公司來說,價值巨大,對用戶來說,沒有價值。所以享元模式的價值體現(xiàn)在全局,比如對整個富文本編輯器來說,減少了巨量字母對象數(shù)量,但對于每一個字母對象而言,并沒有任何優(yōu)化。

結(jié)構(gòu)圖

對于 Client 而言,下圖描述了如何共享 Flyweight:

Flyweight: 共享接口,通過這個接口可以操作對象的外部狀態(tài)。

ConcreteFlyweight: 實現(xiàn) Flyweight 接口的對象,這個對象是可被共享的。

UnsharedConcreteFlyweight: 不被共享的對象,因為在享元模式中,實際上并不是所有對象都可以被共享。

FlyweightFactory: 創(chuàng)建并管理 Flyweight 對象,通過其返回的 Flyweight 對象,如果已創(chuàng)建,則會返回之前創(chuàng)建的那個,沒有的話才會創(chuàng)建一個新的。

Client: 使用 Flyweight 的客戶端。

通過第二個圖可以明顯看到,兩個不同的 Client 持有了相同 aConcreteFlyweight 引用。

代碼例子

下面例子使用 typescript 編寫。

class FlyweightFactory {

  public getFlyWeight(key) {

    if (this.flyweight[key]) {

      return this.flyweight[key]

    }

    const flyweight = new Flyweight()

    this.flyweight[key] = flyweight

    return flyweight

  }

}

FlyweightFactory 提供的 getFlyWeight 方法,實際上是按照 key 對 flyweight 實例進行緩存,相同 key 下只存儲一個 flyweight 實例。

弊端

如果細粒度對象不多,則沒必要使用享元模式。

另外,就算細粒度對象很多,如果對象內(nèi)部狀態(tài)并不多,主要都是外部狀態(tài),那么享元模式就起不到什么作用了,因為享元模式通過共享對象,只能節(jié)省內(nèi)部狀態(tài),而不能節(jié)省外部狀態(tài)。

另外,如果享元模式映射到的共享對象數(shù)量并沒有比原始對象少出數(shù)量級關(guān)系,使用的意義也不大。比如富文本編輯器的例子,對于英文來說,一共就 26 個字母,那么 1 萬字的文章優(yōu)化比例是 10000:26,但對于中文文章而言,文字實例本身就很多,可能 1 萬字的文章中,漢字去重后依然有 3000 個,那么優(yōu)化比例就是 10000:3000,此時享元模式的意義就沒那么打了。

以上就是“Flyweight享元模式怎么實現(xiàn)”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI