?????? GoF
《設(shè)計(jì)模式》中說道:運(yùn)用共享技術(shù)有效的支持大量細(xì)粒度的對(duì)象。
?????? Flyweight
模式的結(jié)構(gòu)大概是這樣的:
??????
(這張圖是按照我的理解畫出來的,如果有不對(duì)的地方還請(qǐng)幫我指正,謝謝),從圖上可以看出
Flyweight
模式是將相同的對(duì)象存為一個(gè),就是在
FlyweightFactory
中對(duì)于實(shí)例化對(duì)象的判斷。這樣,客戶代碼即使是調(diào)用
1000000
個(gè)對(duì)象,如果這些對(duì)象的種類只有一個(gè)的話,對(duì)于內(nèi)存的分配上也只是分配了一個(gè)對(duì)象的空間。但是有一點(diǎn)我想要注意:就是對(duì)于引用對(duì)象來說,這樣做,如果其中某一個(gè)對(duì)象發(fā)生變化,那么同類中的所有對(duì)象也會(huì)隨之變化。
??????
來看看程序,定義一個(gè)場(chǎng)景:有一個(gè)汽車類型,客戶程序要實(shí)例化
1000
個(gè),實(shí)例化后查看一下內(nèi)存分配情況。
??????
普通的面向?qū)ο蠓绞剑?/span>
??????
class
Class1
??? {
??????? [STAThread]
???????
static
void
??????? {
??????????? Console.WriteLine("
實(shí)例化前:"
+ GC.GetTotalMemory(false));
??????????? ArrayList list = new ArrayList(1000);
???????????
for(int i = 0;i < 1000;i++)
??????????? {
??????????????? Car car = new Car("
??????????????? list.Add(car);
??????????? }
??????????? Console.WriteLine("
實(shí)例化后:"
+ GC.GetTotalMemory(false));
??????????? Console.Read();
??????? }
??? }
??????
public
class Car
??? {
???????
private
string body;
???????
private
string wheel;
???????
private
string engine;
???????
private
string brand;
???????
private
string color;??
???????
public
string Body
??????? {
???????????
get{return body;}
???????????
set{body = value;}
??????? }
???????
public
string Wheel
??????? {
???????????
get{return wheel;}
???????????
set{wheel = value;}
??????? }
???????
public
string Engine
??????? {
???????????
get{return engine;}
???????????
set{engine = value;}
??????? }
???????
public
string Brand
??????? {
???????????
get{return brand;}
???????????
set{brand = value;}
??????? }
???????
public
string Color
??????? {
???????????
get{return color;}
???????????
set{color = value;}
??????? }
???????
public Car(string body,string wheel,string engine,string brand,string color)
???
??? {
??????????? Body = body;
??????????? Wheel = wheel;
??????????? Engine = engine;
??????????? Brand = brand;
??????????? Color = color;
??????? }
??? }
???
內(nèi)存分配情況如下:
實(shí)例化前:
16384
實(shí)例化后:
65536
??????
然后再用
Flyweight
模式方式程序做一下比較:
??????
class
Class1
??? {
??????? [STAThread]
???????
static
void
??????? {
??????????? Console.WriteLine("
實(shí)例化前:"
+ GC.GetTotalMemory(false));
??????????? ArrayList list = new ArrayList(1000);
???????????
for(int i = 0;i < 1000;i++)
??????????? {
??????????????? FlyWeightCar car = FlyWeightFactory.CreateInit("
??????????????? list.Add(car);
??????????? }
??????????? Console.WriteLine("
實(shí)例化后:"
+ GC.GetTotalMemory(false));
??????????? Console.Read();
??????? }
??? }
public
class FlyWeightFactory
??? {
???????
private
static FlyWeightCar car;
???????
private
static Hashtable table = new Hashtable();
???????
public
static FlyWeightCar CreateInit(string body,string wheel,string engine,string brand,string color)
??????? {
???????????
if(table[brand] != null)
??????????? {
??????????????? car = (FlyWeightCar)table[brand];
??????????? }
???????????
else
??????????? {
??????????????? car = new FlyWeightCar();
??????????????? car.Brand = brand;
??????????????? car.CarBody = new CarBody(body,wheel,engine,color);
??????????????? table.Add(brand,car);
??????????? }
???????????
return car;
??????? }
??? }
???
public
class FlyWeightCar
??? {
???????
private
string brand;
???????
public
string Brand
??????? {
???????????
get
??????????? {
???????????????
return brand;
??????????? }
???????????
set
??????????? {
??????????????? brand = value;
??????????? }
??????? }
???????
private CarBody carbody;
???????
public CarBody CarBody
??????? {
???????????
get
??????????? {
???????????????
return carbody;
??????????? }
???????????
set
??????????? {
???????????????
this.carbody = value;
??????????? }
??????? }
??? }
???
public
class CarBody
??? {
???????
private
string body;
???????
private
string wheel;
???????
private
string engine;
???????
private
string color;??
???????
public
string Body
??????? {
???????????
get{return body;}
???????????
set{body = value;}
??????? }
???????
public
string Wheel
??????? {
???????????
get{return wheel;}
???????????
set{wheel = value;}
??????? }
???????
public
string Engine
??????? {
???????????
get{return engine;}
???????????
set{engine = value;}
??????? }
???????
public
string Color
??????? {
???????????
get{return color;}
???????????
set{color = value;}
??????? }
???????
public CarBody(string body,string wheel,string engine,string color)
??????? {
??????????? Body = body;
??????????? Wheel = wheel;
??????????? Engine = engine;
??????????? Color = color;
??????? }
??? }
???
內(nèi)存分配情況:
實(shí)例化前:
16384
實(shí)例化后:
40960
??????
從數(shù)字上不難看出內(nèi)存分配的容量節(jié)省了不少,而且隨著數(shù)量的增加,差距會(huì)更大,當(dāng)然我也測(cè)試了一下數(shù)量減少的情況,當(dāng)我實(shí)例化
100
個(gè)對(duì)象是結(jié)果是普通方式的內(nèi)存分配更小一些,所以,在使用時(shí),我們一定要對(duì)所實(shí)例化對(duì)象的個(gè)數(shù)進(jìn)行評(píng)估,否則的話會(huì)適得其反。
?????? Flyweight
模式的幾個(gè)要點(diǎn):
?????? 1
、面向?qū)ο蠛芎玫慕鉀Q了抽象性的問題,但是作為一個(gè)運(yùn)行在機(jī)器中的程序?qū)嶓w,我們需要考慮對(duì)象的代價(jià)問題。
Flyweight
設(shè)計(jì)模式主要解決面向?qū)ο蟮拇鷥r(jià)問題,一般不觸及面向?qū)ο蟮某橄笮詥栴}。
2
、
Flyweight
采用對(duì)象共享的做法來降低系統(tǒng)中對(duì)象的個(gè)數(shù),從而降低細(xì)粒度對(duì)象給系統(tǒng)帶來的內(nèi)存壓力。在具體實(shí)現(xiàn)方面,要注意對(duì)象的狀態(tài)處理。
3 、對(duì)象的數(shù)量太大從而導(dǎo)致對(duì)象內(nèi)存開銷加大(這個(gè)數(shù)量要經(jīng)過評(píng)估,而不能憑空臆斷)