无废话C#设计模式之十:Flyweight

来源:互联网 发布:房地产大数据建设方案 编辑:程序博客网 时间:2024/06/10 20:25
 

意图

 

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

 

场景

 

在比较底层的系统或者框架级的软件系统中,通常存在大量细粒度的对象。即使细力度的对象,如果使用的数量级很高的话会占用很多资源。比如,游戏中可能会在无数个地方使用到模型数据,虽然从数量上来说模型对象会非常多,但是从本质上来说,不同的模型可能也就这么几个。

此时,我们可以引入享元模式来共享相同的模型对象,这样就可能大大减少游戏对资源(特别是内存)的消耗。

 

示例代码

 

using System;

using System.Collections;

using System.Text;

using System.IO;

 

namespace FlyweightExample

{

    class Program

    {

        static void Main(string[] args)

        {

            Console.WriteLine(GC.GetTotalMemory(false));

            Random rnd = new Random();

            ArrayList al = new ArrayList();

            for (int i = 0; i < 10000; i++)

            {

                string modelName = rnd.Next(2).ToString();

                Model model = ModelFactory.GetInstance().GetModel(modelName);

                //Model model = new Model(modelName);

                al.Add(model);

            }

            Console.WriteLine(GC.GetTotalMemory(false));

            Console.ReadLine();

        }

    }

 

    class Model

    {

        private byte[] data;

 

        public Model(string modelName)

        {

            data = File.ReadAllBytes("c://" + modelName + ".txt");

        }

    }

 

    class ModelFactory

    {

        private Hashtable modelList = new Hashtable();

        private static ModelFactory instance;

 

        public static ModelFactory GetInstance()

        {

            if (instance == null)

                instance = new ModelFactory();

            return instance;

        }

 

        public Model GetModel(string modelName)

        {

            Model model = modelList[modelName] as Model;

            if (model == null)

                modelList.Add(modelName, new Model(modelName));

            return model;

        }

    }

}

代码执行结果如下图(前面是使用享元模式的结果,后面是没有使用享元模式的结果):

 

 


代码说明

 

l         这里的ModelFactory就是享元工厂角色。它的作用是创建和管理享元对象。可以看到,每加载一个模型都会在Hashtable中记录一下,之后如果客户端还是需要这个模型的话就直接把已有的模型对象返回给客户端,而不是重新在内存中加载一份模型数据。

l         ModelFactory本身应用了Singleton,因为如果实例化多个享元工厂是的话就起不到统一管理和分配享元对象的目的了。

l         Model就是享元角色。在构造方法中传入modelName,然后它从指定路径加载模型数据,并且把数据放入字段中。

l         从代码的运行结果中可以看到,如果没有应用享元模式,那么在内存中就会有10000套模型对象,由于一共就2个模型,所以9998个对象是可以通过享元来消除的。

 

何时采用

 

l         系统中有大量耗费了大量内存的细粒度对象,并且对外界来说这些对没有任何差别的(或者说经过改造后可以是没有差别的)。

 

实现要点

 

l         享元工厂维护一张享元实例表。

l         享元不可共享的状态需要在外部维护。

l         按照需求可以对享元角色进行抽象。

 

注意事项

 

l         享元模式通常针对细粒度的对象,如果这些对象比较拥有非常多的独立状态(不可共享的状态),或者对象并不是细粒度的,那么就不适合运用享元模式。维持大量的外蕴状态不但会使逻辑复杂而且并不能节约资源。

l         享元工厂中维护了享元实例的列表,同样也需要占用资源,如果享元占用的资源比较小或者享元的实例不是非常多的话(和列表元素数量差不多),那么就不适合使用享元,关键还是在于权衡得失。
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 运输过程中包裹破损怎么办 天猫没收到货签收怎么办 收到的快递坏了怎么办 自寄的快递少了怎么办 邮的东西弄坏了怎么办 物流签收后发现货物损坏怎么办 发现客人损坏了酒店物品怎么办 东西坏了签收了怎么办 朋友圈贩卖三无产品你怎么办 付钱给微商没有保障怎么办 电镀锌钢带生锈怎么办 电机机油从空气滤芯里流出怎么办 把塑料皮套吃了怎么办 塑料框眼镜有点小了怎么办 出口纸箱打了钉怎么办 买房子交款单据丢了怎么办 买房子所有单据丢失怎么办 车险单据都丢了怎么办 真空包装的东西里面有空气怎么办 发货物忘记写唛头了怎么办 Word文档撤销按钮删除了怎么办 ai保存时未响应怎么办 ai还没保存卡了怎么办 ai卡住了没保存怎么办 屁股沟有硬块红肿怎么办 卧室床选太大了怎么办 画板的笔尖掉了怎么办 宜家水壶盖子有水怎么办 背滤鱼缸除油膜怎么办 书多了没地方放怎么办 学生在教室内丢手机怎么办 新车尾箱坏了怎么办 放书的箱子烂了怎么办 车钥匙锁后备箱里怎么办 布的收纳箱有味怎么办 车漆清漆层掉了怎么办 副驾驶储物箱卡子断了怎么办 玛莎拉蒂车门打不开怎么办 新买的水杯漏水怎么办 泰迪小狗掉毛怎么办 手机jlc调用接口状态异常怎么办