Flyweight享元设计模式是一种结构型设计模式,它主要解决的问题是:由于(同类)对象的数量太大,采用面向对象时给系统带来了难以承受的内存开销。比如有这样一个场景:一个停车场中有1000辆汽车,我们所定义的汽车对象占用内存 GoF《设计模式》中说道:运用共享技术有效的支持大量细粒度的对象。 Flyweight模式的结构大概是这样的:
来看看程序,定义一个场景:有一个汽车类型,客户程序要实例化1000个,实例化后查看一下内存分配情况。 普通的面向对象方式: class Class1 { [STAThread] static void { Console.WriteLine("实例化前:" + GC.GetTotalMemory(false)); ArrayList list = new ArrayList(1000); for(int i = 0;i < 1000;i++) { Car car = new Car(" 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 { Console.WriteLine("实例化前:" + GC.GetTotalMemory(false)); ArrayList list = new ArrayList(1000); for(int i = 0;i < 1000;i++) { FlyWeightCar car = FlyWeightFactory.CreateInit(" 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、对象的数量太大从而导致对象内存开销加大(这个数量要经过评估,而不能凭空臆断) |
|