运用共享技术有效地支持大量细粒度的对象-享元模式

一、前言

面向对象技术可以很好地解决一些灵活性或可扩展性问题,但在很多情况下需要在系统中增加类和对象的个数。当对象数量太多时,将导致运行代价过高,带来性能下降等问题。

享元模式正是为解决这一类问题而诞生的。享元模式通过共享技术实现相同或相似对象的重用。

在享元模式中通常会出现工厂模式,需要创建一个享元工厂来负责维护一个享元池用于存储具有相同内部状态的享元对象。

在享元模式中共享的是享元对象的内部状态,外部状态需要通过环境来设置。在实际使用中,能够共享的内部状态是有限的,因此享元对象一般都设计为较小的对象,它所包含的内部状态较少,这种对象也称为细粒度对象。享元模式的目的就是使用共享技术来实现大量细粒度对象的复用。

二、基本概念

享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,它是一种对象结构型模式。

享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。

享元模式四个基本角色:

抽象享元角色(Flyweight):为具体享元角色规定了必须实现的方法,而外蕴状态就是以参数的形式通过此方法传入。

具体享元角色(ConcreteFlyweight):实现抽象角色规定的方法。如果存在内蕴状态,就负责为内蕴状态提供存储空间。

享元工厂角色(FlyweightFactory):负责创建和管理享元角色。要想达到共享的目的,这个角色的实现是关键。

非共享具体享元角色(UnsharedConcreteFlyweight):不需要共享的Flyweight子类。

下面就四个基本角色代码说明

三、基本代码实例

基本代码实现:

      static void Main(string[] args)
        {
            int extrinsicstate = 10;
            FlyweightFactory factory = new FlyweightFactory();
            Flyweight fx = factory.GetFlyweight("X");
            fx.Method(--extrinsicstate);
            Flyweight fy = factory.GetFlyweight("Y");
            fy.Method(--extrinsicstate);
            Flyweight fz = factory.GetFlyweight("Z");
            fz.Method(--extrinsicstate);


            UnsharedConcreteFlyweight uf=new UnsharedConcreteFlyweight();
            uf.Method(--extrinsicstate);

            Console.WriteLine(factory.GetFlyWeightsCount());
            Console.ReadKey();

        }

        // 抽象享元类
        public abstract class Flyweight
        {
            public abstract void Method(int extrinsicstate);
        }

        //具体享元类
        public class ConcreteFlyweight : Flyweight
        {
            public override void Method(int extrinsicstate)
            {
                Console.WriteLine("具体享元类" + extrinsicstate);
            }
        }

        //非共享具体享元类
        public class UnsharedConcreteFlyweight : Flyweight
        {
            public override void Method(int extrinsicstate)
            {
                Console.WriteLine("非共享具体享元类" + extrinsicstate);
            }
        }

        //享元工厂类
        public class FlyweightFactory
        {
            private Hashtable flyweights = new Hashtable();

            //初始化工厂时模式生成三个实例
            public FlyweightFactory()
            {
                flyweights.Add("X", new ConcreteFlyweight());
                flyweights.Add("Y", new ConcreteFlyweight());
                flyweights.Add("Z", new ConcreteFlyweight());
            }

            //根据客户端要求,返回对应的实例
            public Flyweight GetFlyweight(string str)
            {
                return flyweights[str] as Flyweight;
            }

            //获取flyweights实例个数
            public int GetFlyWeightsCount()
            {
                return flyweights.Count;
            }

        }

运行结果:

四、总结

优点:

大大减少对象的创建,降低系统的内存,使效率提高。

缺点:

提高了系统的负责度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱。

何时使用:

1、系统中有大量对象。

2、这些对象消耗大量内存。

3、这些对象的状态大部分可以外部化。

4、这些对象可以按照内蕴状态分为很多组,当把外蕴对象从对象中剔除出来时,每一组对象都可以用一个对象来代替。

5、系统不依赖于这些对象身份,这些对象是不可分辨的。

应用实例:

1、JAVA 中的 String,如果有则返回,如果没有则创建一个字符串保存在字符串缓存池里面。

2、数据库的数据池。

代码下载:

https://yunpan.cn/cqKQnQLEhithe (提取码:a667)

posted @ 2016-03-28 15:03  Joye.Net  阅读(1317)  评论(0编辑  收藏  举报