Flyweight享元設計模式是一種結構型設計模式,它主要解決的問(wèn)題是:由于(同類(lèi))對象的數量太大,采用面向對象時(shí)給系統帶來(lái)了難以承受的內存開(kāi)銷(xiāo)。比如有這樣一個(gè)場(chǎng)景:一個(gè)停車(chē)場(chǎng)中有1000輛汽車(chē),我們所定義的汽車(chē)對象占用內存
GoF《設計模式》中說(shuō)道:運用共享技術(shù)有效的支持大量細粒度的對象。
Flyweight模式的結構大概是這樣的:

(這張圖是按照我的理解畫(huà)出來(lái)的,如果有不對的地方還請幫我指正,謝謝),從圖上可以看出Flyweight模式是將相同的對象存為一個(gè),就是在FlyweightFactory中對于實(shí)例化對象的判斷。這樣,客戶(hù)代碼即使是調用1000000個(gè)對象,如果這些對象的種類(lèi)只有一個(gè)的話(huà),對于內存的分配上也只是分配了一個(gè)對象的空間。但是有一點(diǎn)我想要注意:就是對于引用對象來(lái)說(shuō),這樣做,如果其中某一個(gè)對象發(fā)生變化,那么同類(lèi)中的所有對象也會(huì )隨之變化。
來(lái)看看程序,定義一個(gè)場(chǎng)景:有一個(gè)汽車(chē)類(lèi)型,客戶(hù)程序要實(shí)例化1000個(gè),實(shí)例化后查看一下內存分配情況。
普通的面向對象方式:
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;
}
}
內存分配情況如下:
實(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;
}
}
內存分配情況:
實(shí)例化前:16384
實(shí)例化后:40960
從數字上不難看出內存分配的容量節省了不少,而且隨著(zhù)數量的增加,差距會(huì )更大,當然我也測試了一下數量減少的情況,當我實(shí)例化100個(gè)對象是結果是普通方式的內存分配更小一些,所以,在使用時(shí),我們一定要對所實(shí)例化對象的個(gè)數進(jìn)行評估,否則的話(huà)會(huì )適得其反。
Flyweight模式的幾個(gè)要點(diǎn):
1、面向對象很好的解決了抽象性的問(wèn)題,但是作為一個(gè)運行在機器中的程序實(shí)體,我們需要考慮對象的代價(jià)問(wèn)題。Flyweight設計模式主要解決面向對象的代價(jià)問(wèn)題,一般不觸及面向對象的抽象性問(wèn)題。
2、Flyweight采用對象共享的做法來(lái)降低系統中對象的個(gè)數,從而降低細粒度對象給系統帶來(lái)的內存壓力。在具體實(shí)現方面,要注意對象的狀態(tài)處理。
3、對象的數量太大從而導致對象內存開(kāi)銷(xiāo)加大(這個(gè)數量要經(jīng)過(guò)評估,而不能憑空臆斷)
聯(lián)系客服