设计模式学习笔记(十二)——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)

一、概述 运用共享技术有效地支持大量细粒度的对象。 二、适用性 当都具备下列情况时,使用Flyweight模式:        1.一个应用程序使用了大量的对象。        2.完全由于使用大...
  • l1028386804
  • l1028386804
  • 2015年05月07日 23:46
  • 1577

设计模式(结构型)之享元模式(Flyweight Pattern)

当一个软件系统在运行时产生的对象数量太多,将导致运行代价过高,带来系统性能下降等问题。所以需要采用一个共享来避免大量拥有相同内容对象的开销。在Java中,String类型就是使用了享元模式。Strin...
  • yanbober
  • yanbober
  • 2015年05月04日 14:15
  • 2933

C++设计模式13----Flyweight享元模式

Flyweight享元模式概述 作用:运用共享技术有效地支持大量细粒度的对象。 内部状态intrinsic和外部状态extrinsic: 1)Flyweight模式中,最重要的是将对象分解成intri...
  • gatieme
  • gatieme
  • 2015年02月09日 20:46
  • 12033

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

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

PHP设计模式——享元模式

声明:本系列博客参考资料《大话设计模式》,作者程杰。         享元模式使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于只是因重复而导致使用无法令人接受的大量内...
  • jhq0113
  • jhq0113
  • 2015年05月16日 13:06
  • 1751

JAVA设计模式之享元模式

解释一下概念:也就是说在一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象。比如说一个文本系统,每个字母定一个对象,那么大小写字母一共就是52个,那么就要定义52个对象...
  • jason0539
  • jason0539
  • 2014年04月04日 07:34
  • 30965

Android设计模式之享元模式(Flyweight Pattern)

一 享元模式介绍:1.1 使用享元模式有什么好处? 享元模式是对象池的一种实现,主要目的是用来尽可能减少内存使用量。适合于存在大量重复对象的场景,来缓存可共享的对象,达到对象共享,避免创建过多对象...
  • happy_horse
  • happy_horse
  • 2016年04月14日 15:56
  • 910

设计模式读书笔记-----享元模式

面向对象可以非常方便的解决一些扩展性的问题,但是在这个过程中系统务必会产生一些类或者对象,如果系统中存在对象的个数过多时,将会导致系统的性能下降。对于这样的问题解决最简单直接的办法就是减少系统中对象的...
  • chenssy
  • chenssy
  • 2013年09月20日 16:49
  • 6747

Java设计模式(十二)----享元模式

享元模式 一、 概念 二、享元的用途 三、结构和分类 1、单纯享元模式  2、复合享元模式 四、享元模式的优缺点 一、概念  Flyweight在拳击比赛中指最轻量级,即“蝇量级”...
  • tanggao1314
  • tanggao1314
  • 2016年01月31日 16:17
  • 1452

Java设计模式——享元模式

在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。...
  • u013761665
  • u013761665
  • 2016年04月25日 13:35
  • 10907
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:设计模式学习笔记(十二)——Flyweight享元模式
举报原因:
原因补充:

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