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

意图

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

场景

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

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

示例代码

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 ;

        }

    }

}

时间: 2024-09-14 17:51:46

无废话C#设计模式之十:Flyweight的相关文章

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

意图 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新. 场景 这次不说游戏了,假设我们需要在一个Web页面上分页显示数据.首先需要一个分页控制器和一个显示数据的表格.开始,客户的需求很简单,需要两个向前翻页向后翻页的按钮作为控制器,还需要一个GridView来显示数据.你可能会这么做: l 在页面上放两个按钮和一个GridView控件 l 点击了下一页按钮判断是否超出了页面索引,如果没有的话更新GridView中的数据,然后更新控件的当前

无废话C#设计模式之十四:Template Method

意图 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 场景 模版方法是非常容易理解的设计模式,一来是因为它没有过多结构上的交错,二来是因为这种代码复用技术对于掌握OO知识的人来说非常容易可以想到,很可能你已经在很多地方运用了模版方法.在运用一些设计模式的时候常常也会一起运用模版方法,甚至有的设计模式本身就带有模版方法的思想. 今天,我们给出这样一个实际的例子.做过银行支付.支付宝支付的人都知道,

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

意图 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤消的操作. 场景 我们知道,网络游戏中的客户端需要不断把当前人物的信息发送到游戏服务端进行处理(计算合法性.保存状态到数据库等).假设有这样一种需求,在服务端收到客户端的请求之后需要判断两次请求间隔是不是过短,如果过短的话就考虑可能是游戏外挂,不但不执行当前请求还要把前一次请求进行回滚.暂且把问题简单化一点不考虑客户端和服务端之间的通讯来进行程序设计的话,你可能会创建一个Man类型,其中

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

意图 允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类. 场景 我们在制作一个网上书店的网站,用户在书店买了一定金额的书后可以升级为银会员.黄金会员,不同等级的会员购买书籍有不同的优惠.你可能会想到可以在User类的BuyBook方法中判断用户历史消费的金额来给用户不同的折扣,在GetUserLevel方法中根据用户历史消费的金额来输出用户的等级.带来的问题有三点: l 不用等级的用户给予的优惠比率是经常发生变化的,一旦变化是不是就要修改User类呢? l 网站在初期可能最

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

意图 定义一系列的算法,把它们一个一个封装起来,并且使它们可相互替换.本模式使得算法可以独立于它的客户而变化. 场景 在开发程序的时候,我们经常会根据环境不同采取不同的算法对对象进行处理.比如,在一个新闻列表页面需要显示所有新闻,而在一个新闻搜索页面需要根据搜索关键词显示匹配的新闻.如果在新闻类内部有一个ShowData方法的话,那么我们可能会传入一个searchWord的参数,并且在方法内判断如果参数为空则显示所有新闻,如果参数不为空则进行搜索.如果还有分页的需求,那么还可能在方法内判断是否分

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

意图 将抽象部分与实现部分分离,使它们都可以独立的变化. 场景 还是说我们要做的网络游戏,多个场景需要扩充的问题我们已经采用了创建型模式来解决.现在的问题就是,不仅仅是游戏场景会不断扩充,而且游戏的模式也在不断扩充.比如,除了最基本的战斗模式之外,还会有道具模式,金币模式等. 对于这种在多个维度上都会有变化或扩充需求的项目来说,可以考虑引入桥接模式.或许你会说,不管是什么场景,不管什么模式,都可以是抽象场景的一个子类,但是,如果这样的话,4个场景和3种模式就会产生12个子类,而10个场景5种模式

无废话C#设计模式之二十二:总结(针对GOF23)

本文配套源码 比较 设计模式 常用程度 适用层次 引入时机 结构复杂度 Abstract Factory 比较常用 应用级 设计时 比较复杂 Builder 一般 代码级 编码时 一般 Factory Method 很常用 代码级 编码时 简单 Prototype 不太常用 应用级 编码时.重构时 比较简单 Singleton 很常用 代码级.应用级 设计时.编码时 简单 Adapter 一般 代码级 重构时 一般 Bridge 一般 代码级 设计时.编码时 一般 Composite 比较常用

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

意图 用一个中介对象来封装一系列对象的交互.中介者使得各对象不需要显式相互引用,从而使其松散耦合,而且可以独立地改变它们之间的交互. 场景 我们知道,一个网络游戏往往有很多大区.每一个大区可以是一组服务器,也可以是多组服务器,在这里假设一个大区是一组服务器.为了效率,一般每个大区都会有一个数据库,玩家的创建角色.充值.消费行为只是在这一个大区中有效.现在公司有了新的需求,那就是玩家的一些信息能在多个大区中共享.比如,在注册的时候就把玩家的账户信息写入多个信息共享的大区,玩家在某个大区中充值需要"

无废话C#设计模式之五:Prototype

意图 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 场景 游戏场景中的有很多相似的敌人,它们的技能都一样,但是随着敌人出现的位置不同,这些人的能力不太一样.假设,我们现在需要把三个步兵组成一队,其中还有一个精英步兵,能力特别高.那么,你或许可以创建一个敌人抽象类,然后对于不同能力的步兵创建不同的子类.然后,使用工厂方法等设计模式让调用方依赖敌人抽象类. 问题来了,如果有无数种能力不同步兵,难道需要创建无数子类吗?还有,步兵模型的初始化工作是非常耗时的,创建这么多步兵对象可能还