自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Go設(shè)計(jì)模式--享元模式,節(jié)省內(nèi)存的好幫手

開發(fā) 前端
享元模式其實(shí)是對(duì)象池的一種應(yīng)用,在應(yīng)用該模式之前, 我們需要確定程序中確實(shí)存在著大量擁有相同狀態(tài)(字段)的相似對(duì)象同時(shí)占用內(nèi)存的問題。

大家好,這里是每周都在陪你一起進(jìn)步的網(wǎng)管~!今天繼續(xù)學(xué)習(xí)設(shè)計(jì)模式—享元模式

享元模式是一種結(jié)構(gòu)型設(shè)計(jì)模式, 它的核心思想是通過共享多個(gè)對(duì)象所共有的相同狀態(tài),從而有效的支持在有限的內(nèi)存中載入大量細(xì)粒度的對(duì)象。

這里著重介紹一下享元這個(gè)名詞,享元可以理解為可復(fù)用的對(duì)象,即可以是對(duì)象級(jí)別的復(fù)用,也可以是對(duì)象的字段進(jìn)行復(fù)用(把可復(fù)用的字段單獨(dú)提煉成一個(gè)更精細(xì)的對(duì)象)。

享元模式的意圖是復(fù)用對(duì)象,節(jié)省內(nèi)存,前提是享元對(duì)象是不可變對(duì)象,不可變對(duì)象指的是初始化之后,對(duì)象的狀態(tài)不會(huì)改變了,也就是不會(huì)存在被修改的情況。

使用場景

當(dāng)一個(gè)系統(tǒng)中有大量的重復(fù)對(duì)象的時(shí)候,如果這些對(duì)象是不可變對(duì)象,我們就可以使用享元模式,將這些對(duì)象設(shè)計(jì)成享元,在內(nèi)存只保存一份,供需要的代碼使用,這樣能減少內(nèi)存中對(duì)象的數(shù)量,起到節(jié)省內(nèi)存的作用。

實(shí)際上,不僅僅相同對(duì)象可以設(shè)計(jì)成享元,對(duì)于相似對(duì)象,我們也可以將這些對(duì)象中相同的部分(字段)提取出來,設(shè)計(jì)成享元,讓這些大量相似對(duì)象引用這些享元。

實(shí)現(xiàn)思路

享元模式的實(shí)現(xiàn)思路是,在享元對(duì)象的工廠類中,通過一個(gè) Map 來緩存已經(jīng)創(chuàng)建的享元對(duì)象,達(dá)到復(fù)用的目的。接下來我們用一個(gè)例子來了解下怎么使用享元模式。

享元模式舉例

假設(shè)我們要設(shè)計(jì)一個(gè)多人在線棋牌游戲的平臺(tái)。在每個(gè)牌局里我們會(huì)給用戶發(fā)牌然后進(jìn)行對(duì)戰(zhàn),如果在平臺(tái)中每創(chuàng)建一個(gè)牌局就需要初始化對(duì)應(yīng)的卡牌,這樣顯然很浪費(fèi),因?yàn)橐惶讚淇伺评锏目ㄅ剖枪潭ǖ?,不管多少個(gè)牌局使用的撲克牌都是一樣的,只是牌的玩法不一樣。

撲克牌在這里就相當(dāng)于不可變對(duì)象,創(chuàng)建后即不可改變,而牌局是外在對(duì)象,有對(duì)應(yīng)的狀態(tài)變化,我們只需要讓每個(gè)牌局引用撲克牌這些享元即能達(dá)到在有限的內(nèi)存里多開牌局的目的。

所以我們可以設(shè)計(jì)一個(gè) pokerCards 存儲(chǔ)多個(gè)享元撲克牌對(duì)象:

var pokerCards = map[int]*Card{
1: {
Name: "A",
Color: "紅",
},
2: {
Name: "A",
Color: "黑",
},
// 其他卡牌
}

type Card struct {
Name string
Color string
}

每個(gè)牌局創(chuàng)建時(shí)程序會(huì)設(shè)定牌局里的卡牌都引用自pokerCards中的享元

"本文使用的完整可運(yùn)行源碼
去公眾號(hào)「網(wǎng)管叨bi叨」發(fā)送【設(shè)計(jì)模式】即可領(lǐng)取"
type PokerGame struct {
Cards map[int]*Card
}

func NewPokerGame() *PokerGame {
board := &PokerGame{Cards: map[int]*Card{}}
for id := range pokerCards {
board.Cards[id] = pokerCards[id]
}
return board
}

具體牌局的規(guī)則是什么該怎么打,這些業(yè)務(wù)邏輯以及牌局的進(jìn)行狀態(tài)等這些外部狀態(tài)都由PokerGame類型來實(shí)現(xiàn),示例代碼這里不再過多著墨說明。這里的重點(diǎn)是享元始終是不可改變的,這樣才能保證享元在系統(tǒng)中只有一份,起到節(jié)省內(nèi)存的作用。

運(yùn)行程序我們可以驗(yàn)證,兩個(gè)牌局都引用了享元,系統(tǒng)中不存在相同享元對(duì)象的多次創(chuàng)建。

func main() {
game1 := NewPokerGame()
game2 := NewPokerGame()
fmt.Println(game1.Cards[1] == game2.Cards[1])
}

本文的完整源碼,已經(jīng)同步收錄到我整理的電子教程里啦,可向我的公眾號(hào)「網(wǎng)管叨bi叨」發(fā)送關(guān)鍵字【設(shè)計(jì)模式】領(lǐng)取。

圖片

公眾號(hào)「網(wǎng)管叨bi叨」發(fā)送關(guān)鍵字【設(shè)計(jì)模式】領(lǐng)取。

這里享元模式用代碼實(shí)現(xiàn)的比較簡單,主要為了突出享元的不可變,而代表業(yè)務(wù)當(dāng)前狀態(tài)的外部狀態(tài)都是存儲(chǔ)在引用了享元的容器對(duì)象中。

下面我們?cè)賮碛?UML 類圖梳理一下享元模式的結(jié)構(gòu)

享元模式的結(jié)構(gòu)

圖片

享元模式的結(jié)構(gòu)中有一下幾個(gè)角色:

  • Context:上下文或者叫做情景類,包含原始對(duì)象中各不相同的外在狀態(tài)。 情景與享元對(duì)象組合在一起就能表示原始對(duì)象的全部狀態(tài)。調(diào)用享元方法的參數(shù)由情景類提供,也可將行為移動(dòng)到情景類中, 然后將連入的享元作為單純的數(shù)據(jù)對(duì)象。
  • Flyweight:享元類,包含原始對(duì)象中部分能在多個(gè)對(duì)象中共享的狀態(tài)。 同一享元對(duì)象可在許多不同情景中使用。 享元中存儲(chǔ)的狀態(tài)被稱為 “內(nèi)在狀態(tài)”。 傳遞給享元方法的狀態(tài)被稱為 “外在狀態(tài)”。
  • FlyweightFactory:享元工廠,會(huì)對(duì)已有享元的緩存池進(jìn)行管理。 有了工廠后, 客戶端就無需直接創(chuàng)建享元, 它們只需調(diào)用工廠并向其傳遞目標(biāo)享元的一些內(nèi)在狀態(tài)即可。 工廠會(huì)根據(jù)參數(shù)在之前已創(chuàng)建的享元中進(jìn)行查找, 如果找到滿足條件的享元就將其返回; 如果沒有找到就根據(jù)參數(shù)新建享元。

總結(jié)

享元模式其實(shí)是對(duì)象池的一種應(yīng)用,在應(yīng)用該模式之前, 我們需要確定程序中確實(shí)存在著大量擁有相同狀態(tài)(字段)的相似對(duì)象同時(shí)占用內(nèi)存的問題。

享元模式的優(yōu)點(diǎn)是能減少對(duì)象的創(chuàng)建,降低內(nèi)存中對(duì)象的數(shù)量,降低系統(tǒng)的內(nèi)存,提高效率。其缺點(diǎn)是 我們?cè)趯懗绦驎r(shí)需要關(guān)注內(nèi)、外部狀態(tài),關(guān)注線程安全問題,使系統(tǒng)、程序的邏輯復(fù)雜化。

所以在使用的時(shí)候我們需要綜合考慮,確定系統(tǒng)存在大量相似對(duì)象占用內(nèi)村過多的問題,這些對(duì)象的一些特征字段也確實(shí)能提煉成不可變對(duì)象作為享元讓外部對(duì)象進(jìn)行引用,再考慮使用該模式。

責(zé)任編輯:武曉燕 來源: 網(wǎng)管叨bi叨
相關(guān)推薦

2020-05-25 10:20:19

享元模式場景

2024-02-27 11:59:12

享元模式對(duì)象

2022-06-20 08:16:42

享元模式優(yōu)化系統(tǒng)內(nèi)存

2021-04-19 21:25:48

設(shè)計(jì)模式到元

2023-05-04 08:47:31

命令模式抽象接口

2024-04-12 12:10:18

Python設(shè)計(jì)模式開發(fā)

2023-04-10 09:20:13

設(shè)計(jì)模式訪客模式

2021-08-10 09:04:43

內(nèi)存視圖 NumPy

2021-08-10 13:17:31

NumPy內(nèi)存Python

2023-05-15 08:51:46

解釋器模式定義

2023-05-26 08:41:23

模式Go設(shè)計(jì)模式

2012-02-22 15:17:24

Autodesk美家達(dá)人

2011-04-13 09:13:02

Java內(nèi)存

2024-05-17 10:08:59

享元模式分類方式

2013-06-17 14:03:27

IIS日志網(wǎng)站運(yùn)維

2011-04-06 14:20:50

Java編程

2020-02-25 17:40:52

Python循環(huán)內(nèi)存

2021-06-09 10:59:46

享元模式設(shè)計(jì)

2009-09-07 09:33:35

Unix系統(tǒng)LVM硬盤管理

2023-03-21 07:57:37

Go語言設(shè)計(jì)模式
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)