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

2016-02-19 13:47 0 1 收藏

有了下面这个无废话C#设计模式之十:Flyweight教程,不懂无废话C#设计模式之十:Flyweight的也能装懂了,赶紧get起来装逼一下吧!

【 tulaoshi.com - 编程语言 】

  本系列文章将向大家介绍一下C#的设计模式,此为第十篇文章,相信对大家会有所帮助的。废话不多说,继续来看。

  意图

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

  场景

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

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

  示例代码

以下是引用片段:
  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;
  }
  }
  }

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

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

  

  

  代码说明

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

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

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

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

  何时采用

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

  实现要点

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

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

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

  注意事项

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

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

  享元工厂中维护了享元实例的列表,同样也需要占用资源,如果享元占用的资源比较小或者享元的实例不是非常多的话(和列表元素数量差不多),那么就不适合使用享元,关键还是在于权衡得失。

  上一篇:无废话C#设计模式之九:Proxy
  下一篇:无废话C#设计模式之十一:Composite

来源:https://www.tulaoshi.com/n/20160219/1605212.html

延伸阅读
大家好,我是SUNWEN.今天下午得知,晚上要去当"更夫".呵呵,我们这个学校很是奇怪,要叫我们轮流去通宵巡逻,从晚上10:30到早上6:00.我有一个物理系的朋友,上次在田家炳楼门前找了一个宣传板,垫在下面就睡了一觉,听了笑死我了!哈哈! 现在我想说的是C#中的容器.这是一个非常重要的话题,因为不管你写什么样的程序,你都不能不与容...
C#代码的外观和操作方式与C++和Java非常类似。初看起来,其语法可能比较混乱,不像书面英语和其他语言。但是,在C#编程中,使用的样式是比较清晰的,不用花太多的力气就可以编写出可读性很强的代码。 与其他语言的编译器不同,无论代码中是否有空格、回车符或tab字符(这些字符统称为空白字符),C#编译器都不考虑这些字符。这样格式化...
本文目的:根据近期开发的C#软件,对于软件的启动设计谈谈我的心得。 如下代码是我设计的启动软件的类,应用程序入口也是在这个普通类里面。 using System; using System.Threading; using System.Windows.Forms; namespace MainClass { public class MainApp { private static Mutex myMutex; private static bool requestInitialOwnersh...
C#中程序结构的关键概念为程序、命名空间、类型、成员和程序集。C#程序包括一个或多个源文件。程序中声明类型,类型包含成员并能够被组织到命名空间中。类和接口是类型的例子。字段、方法、属性和事件则是成员的例子。当C#程序被编译时,它们被物理地打包到程序集中。程序集的文件扩展名一般为.exe或者.dll,这取决于它们是实现为应用程序...
大家好,我是SUNWEN.今天下午得知,晚上要去当"更夫".呵呵,我们这个学校很是奇怪,要叫我们轮流去通宵巡逻,从晚上10:30到早上6:00.我有一个物理系的朋友,上次在田家炳楼门前找了一个宣传板,垫在下面就睡了一觉,听了笑死我了!哈哈! 现在我想说的是C#中的容器.这是一个非常重要的话题,因为不管你写什么样的程序,你都不能不与容器打交道.什么是容器...

经验教程

770

收藏

52
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部