flyweight模式也叫享元模式,是構造型模式之一,它通過與其他類似物件共享資料來減小記憶體占用。
換句話說就是通過共享的方式高效地支援大量細粒度的物件。
享元模式的結構:
享元模式的角色和職責:
優缺點:
優點:缺點:適用場合:
我們有乙個景觀設計軟體專案:
需要布置很多的樹:xy座標,樹的大小,外觀
假如需要10000000棵樹,我們該怎麼設計呢?
首先的想法就是抽象乙個樹的類,然後使用的時候初始化10000000個樹的例項。
按照這種方式具體的實現一下:
public
class
tree
public
void
display()
}
public
class
treestest
}public
void
display()
}}
public
class
maintest
public
static
void
showmeminfo()
}
看一下執行的結果吧
最大記憶體 = 926941184我們這時候發現我們需要多少的樹就要new出多少個樹的物件,占用記憶體。已分配記憶體 = 64487424
已分配記憶體中的剩餘空間 = 62465304
已用記憶體 = 2022120
時間 = 1539587641214
最大記憶體 = 926941184
已分配記憶體 = 361234432
已分配記憶體中的剩餘空間 = 79750928
已用記憶體 = 281483504
時間 = 1539587644567
最大記憶體 = 926941184
已分配記憶體 = 361234432
已分配記憶體中的剩餘空間 = 79750928
已用記憶體 = 281483504
時間 = 1539587644583
看一下樹這個類,他的有些狀態是共享的,如display這個方法,每乙個樹的顯示都是一樣的,然後像具體的座標和年齡這個資訊都相當於外部的狀態,每乙個都是不同的,我們可以設計乙個新的類來管理這些資訊,然後在例項化樹的物件的時候就只需要例項化乙個,然後每個樹得資訊從管理類中獲取。那個管理的類中其實就是虛擬化了很多的樹的類。這其實就是享元模式的設計思想,把相似的物件的資料進行共享。
看下具體的實現:
public
class
treeflyweight
public
void
display
(int xcoord,
int ycoord,
int age)
}
public
class
treemanager
}public
void
displaytrees()
}}
public
class
maintest
public
static
void
showmeminfo()
}
看一下執行結果:
最大記憶體 = 926941184通過比較發現記憶體被占用變小了,執行時間變小了。已分配記憶體 = 64487424
已分配記憶體中的剩餘空間 = 62465304
已用記憶體 = 2022120
時間 = 1539588509988
最大記憶體 = 926941184
已分配記憶體 = 145227776
已分配記憶體中的剩餘空間 = 22870040
已用記憶體 = 122357736
時間 = 1539588510873
最大記憶體 = 926941184
已分配記憶體 = 145227776
已分配記憶體中的剩餘空間 = 22870040
已用記憶體 = 122357736
時間 = 1539588510881
其實享元模式就是通過共享細粒度物件的資料減少物件的資料的初始化或者是減少例項物件的建立。
再看乙個更加複雜一點的例子。就是上面的景觀專案,我不只要栽樹,還要栽花。
這時候使用享元模式的設計的類圖如下所示:
我們把草和樹都抽象成為了乙個plant的類,然後使用plantmanager來統一管理外部狀態資料。但是有人說當我需要放置雕像的時候怎麼辦呢?那就直接把雕像單獨作為乙個類,然後抽象乙個manager來做統一的管理。以後每新增乙個物件要是可以抽象成為一組的就抽象,不能抽象成為一組的就直接單獨成為一類。
看一下具體的**實現:
public
class
tree
extends
plant
}
public
class
grass
extends
plant
}
public
abstract
class
plant
public
abstract
void
display
(int xcoord,
int ycoord,
int age)
;}
public
class
plantmanager
}public
void
displaytrees()
}}
public
class
plantfactory
public plant getplant
(int type)
}return plantmap.
get(type);}
}
plantfactory是用來管理和獲取具體的plant型別的。
public
class
maintest
public
static
void
showmeminfo()
}
看一下測試類的結果:
最大記憶體 = 926941184通過結果我們可以看出儘管新增了乙個新的類,但是記憶體占用和執行時間還是比初始的時候要小。已分配記憶體 = 64487424
已分配記憶體中的剩餘空間 = 62465304
已用記憶體 = 2022120
時間 = 1539589480028
最大記憶體 = 926941184
已分配記憶體 = 185597952
已分配記憶體中的剩餘空間 = 23240200
已用記憶體 = 162357752
時間 = 1539589481484
最大記憶體 = 926941184
已分配記憶體 = 185597952
已分配記憶體中的剩餘空間 = 23240200
已用記憶體 = 162357752
時間 = 1539589481658
所以可以看出享元模式的好處。
設計模式18 蠅量 享元 模式
大量的微小的物件,物件屬性拆開 內部屬性和外部屬性拆開 比如樹物件,普通設計為 有乙個集合儲存樹物件,每個物件有其對應的橫座標,縱座標,及年齡 而蠅量模式為 多個集合 每個集合長度一樣 第乙個集合儲存所有虛擬樹物件,第二個儲存所有樹的橫座標,第三個儲存樹的所有縱座標,第四個儲存所有樹的年齡.在需要的...
二十三種設計模式之蠅量模式 享元模式
蠅量模式 享元模式 通過共享方式高效支援大量細粒度物件.將乙個物件抽象出內部屬性作為蠅量物件 抽象出外部屬性 作為管理外部狀態 特點 減少執行時物件例項的個數,節省開銷和記憶體 public classtree public voiddisplay public classtreetest publ...
設計模式之蠅量模式
模式定義 該模式以共享的方式高效地支援大量的細粒度物件。通過復用記憶體中已經存在的物件,降低系統建立物件的效能消耗。遵循原則 共享細粒度物件,降低記憶體消耗 分開變化和不變部分。適用場合 1 當系統中某物件型別的例項比較多的時候 2 在系統設計時,物件例項進行分類後,發現真正有區別的分類很少的時候。...