设计模式学习笔记(十二)——Flyweight享元模式

原创 2007年09月18日 16:46:00
设计模式学习笔记(十二)——Flyweight享元模式

   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设计模式主要解决面向对象的代价问题,一般不触及面向对象的抽象性问题。

2Flyweight采用对象共享的做法来降低系统中对象的个数,从而降低细粒度对象给系统带来的内存压力。在具体实现方面,要注意对象的状态处理。

3、对象的数量太大从而导致对象内存开销加大(这个数量要经过评估,而不能凭空臆断)

 

相关文章推荐

Java面向对象设计模式(十二)——享元模式(Flyweight)

相关文章:Java面向对象设计模式 享元模式(Flyweight) 享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。 ...

设计模式学习笔记--享元(Flyweight)模式

享元模式以共享的方式高效地支持大量的细粒度对象。享元模式分为单纯享元模式和复合享元模式。享元模式不是一种常用的模式,我个人不曾记得哪个项目真正使用过享元模式。...

设计模式学习笔记之Flyweight模式(享元模式)

GOF:运用共享技术有效地支持大量细粒度的对象。   解释一下概念:也就是说在一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象。比如说(这里引用GOF书中的例...

浅谈Java设计模式(十二)享元模式(Flyweight)

前言: 享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。 FlyWeightFactory负责创建和管理享元单元,当一...

十二、状态模式——设计模式学习笔记

状态模式,当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。...

设计模式读书笔记:Flyweight(享元)

意图: 运用共享技术有效地支持大量细粒度的对象。

设计模式 笔记 享元模式 Flyweight

//---------------------------15/04/20---------------------------- //Flyweight 享元模式---...
  • boydfd
  • boydfd
  • 2015年04月21日 09:06
  • 663

设计模式笔记19:享元模式(Flyweight Pattern)

一、享元模式的内容 享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享...

设计模式读书笔记之享元模式(Flyweight pattern)

享元模式:运用共享技术支持大量细粒度的对象。 记得我年前我读过一次享元模式,当时因为所看的书中的例子不是很好懂,就觉得享元模式无非就是搞个缓冲池保存一些对象然后被共享以免重复创造。 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:设计模式学习笔记(十二)——Flyweight享元模式
举报原因:
原因补充:

(最多只允许输入30个字)