Franky's LIFE

          Anything... ...

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            53 隨筆 :: 87 文章 :: 6 評(píng)論 :: 0 Trackbacks
          Flyweight 享元設(shè)計(jì)模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,它主要解決的問題是:由于(同類)對(duì)象的數(shù)量太大,采用面向?qū)ο髸r(shí)給系統(tǒng)帶來了難以承受的內(nèi)存開銷。比如有這樣一個(gè)場(chǎng)景:一個(gè)停車場(chǎng)中有 1000 輛汽車,我們所定義的汽車對(duì)象占用內(nèi)存 0.3M ,那么要實(shí)例化 1000 輛就是 300M 。由此可見,在這種情況下采用一般的面向?qū)ο蠓绞匠霈F(xiàn)了大量細(xì)粒度的對(duì)象會(huì)很快充斥在系統(tǒng)中,從而帶來很高的運(yùn)行是代價(jià)(這里指的代價(jià)是內(nèi)存開銷的代價(jià))。

          ?????? 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 Main(string[] args)

          ??????? {

          ??????????? Console.WriteLine(" 實(shí)例化前:" + GC.GetTotalMemory(false));

          ??????????? ArrayList list = new ArrayList(1000);

          ??????????? for(int i = 0;i < 1000;i++)

          ??????????? {

          ??????????????? Car car = new Car("4.2M","Wheel","NeedForSpeed","BMW","Black");

          ??????????????? 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 Main(string[] args)

          ??????? {

          ??????????? Console.WriteLine(" 實(shí)例化前:" + GC.GetTotalMemory(false));

          ??????????? ArrayList list = new ArrayList(1000);

          ??????????? for(int i = 0;i < 1000;i++)

          ??????????? {

          ??????????????? FlyWeightCar car = FlyWeightFactory.CreateInit("4.2M","Wheel","NeedForSpeed","BMW","Black");

          ??????????????? 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)估,而不能憑空臆斷)

          posted on 2007-03-19 20:59 Franky 閱讀(153) 評(píng)論(0)  編輯  收藏 所屬分類: IT知識(shí)
          主站蜘蛛池模板: 漳浦县| 原阳县| 化州市| 东阳市| 芜湖市| 白水县| 宁晋县| 周宁县| 会宁县| 葫芦岛市| 比如县| 峨山| 廊坊市| 西贡区| 尖扎县| 灵川县| 沁阳市| 珲春市| 永宁县| 南溪县| 亳州市| 长治县| 米林县| 自治县| 泰兴市| 洱源县| 乌拉特中旗| 汝州市| 东光县| 余庆县| 晋中市| 毕节市| 游戏| 德化县| 铜梁县| 元阳县| 荔波县| 永宁县| 石阡县| 陕西省| 饶平县|