Franky's LIFE

          Anything... ...

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            53 隨筆 :: 87 文章 :: 6 評論 :: 0 Trackbacks
          Flyweight 享元設計模式是一種結構型設計模式,它主要解決的問題是:由于(同類)對象的數量太大,采用面向對象時給系統帶來了難以承受的內存開銷。比如有這樣一個場景:一個停車場中有 1000 輛汽車,我們所定義的汽車對象占用內存 0.3M ,那么要實例化 1000 輛就是 300M 。由此可見,在這種情況下采用一般的面向對象方式出現了大量細粒度的對象會很快充斥在系統中,從而帶來很高的運行是代價(這里指的代價是內存開銷的代價)。

          ?????? GoF 《設計模式》中說道:運用共享技術有效的支持大量細粒度的對象。

          ?????? Flyweight 模式的結構大概是這樣的:


          ??????
          (這張圖是按照我的理解畫出來的,如果有不對的地方還請幫我指正,謝謝),從圖上可以看出 Flyweight 模式是將相同的對象存為一個,就是在 FlyweightFactory 中對于實例化對象的判斷。這樣,客戶代碼即使是調用 1000000 個對象,如果這些對象的種類只有一個的話,對于內存的分配上也只是分配了一個對象的空間。但是有一點我想要注意:就是對于引用對象來說,這樣做,如果其中某一個對象發生變化,那么同類中的所有對象也會隨之變化。

          ?????? 來看看程序,定義一個場景:有一個汽車類型,客戶程序要實例化 1000 個,實例化后查看一下內存分配情況。

          ?????? 普通的面向對象方式:

          ?????? class Class1

          ??? {

          ??????? [STAThread]

          ??????? static void Main(string[] args)

          ??????? {

          ??????????? Console.WriteLine(" 實例化前:" + 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(" 實例化后:" + 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;

          ??????? }

          ??? }

          ??? 內存分配情況如下:

          實例化前: 16384

          實例化后: 65536

          ?????? 然后再用 Flyweight 模式方式程序做一下比較:

          ?????? class Class1

          ??? {

          ??????? [STAThread]

          ??????? static void Main(string[] args)

          ??????? {

          ??????????? Console.WriteLine(" 實例化前:" + 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(" 實例化后:" + 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;

          ??????? }

          ??? }

          ??? 內存分配情況:

          實例化前: 16384

          實例化后: 40960

          ?????? 從數字上不難看出內存分配的容量節省了不少,而且隨著數量的增加,差距會更大,當然我也測試了一下數量減少的情況,當我實例化 100 個對象是結果是普通方式的內存分配更小一些,所以,在使用時,我們一定要對所實例化對象的個數進行評估,否則的話會適得其反。

          ?????? Flyweight 模式的幾個要點:

          ?????? 1 、面向對象很好的解決了抽象性的問題,但是作為一個運行在機器中的程序實體,我們需要考慮對象的代價問題。 Flyweight 設計模式主要解決面向對象的代價問題,一般不觸及面向對象的抽象性問題。

          2 Flyweight 采用對象共享的做法來降低系統中對象的個數,從而降低細粒度對象給系統帶來的內存壓力。在具體實現方面,要注意對象的狀態處理。

          3 、對象的數量太大從而導致對象內存開銷加大(這個數量要經過評估,而不能憑空臆斷)

          posted on 2007-03-19 20:59 Franky 閱讀(153) 評論(0)  編輯  收藏 所屬分類: IT知識
          主站蜘蛛池模板: 卢湾区| 育儿| 桓台县| 寻甸| 越西县| 承德县| 黎平县| 靖江市| 县级市| 永德县| 长春市| 来宾市| 万全县| 台南市| 绍兴县| 上栗县| 诸城市| 公主岭市| 沁阳市| 禄丰县| 菏泽市| 唐河县| 溆浦县| 饶平县| 横峰县| 无极县| 迭部县| 巴南区| 朔州市| 饶平县| 五原县| 渝中区| 金秀| 鄱阳县| 会泽县| 平顺县| 黎川县| 固始县| 芦山县| 米脂县| 页游|