• 享元模式 -- 大话设计模式


    在今天,读书有时是件“麻烦”事。它需要你付出时间,付出精力,还要付出一份心境。--仅以《大话设计模式》来祭奠那逝去的……

    享元模式:运用共享技术有效地支持大量细粒度的对象,避免大量的相似对象的开销

    程序设计中,有时需要大量细粒度的对象。如果能从这些对象中发现除了几个参数不同其他都是相同的话,可以通过将这些相同参数移到实例外,构建享元类,在方法调用时将具体对象传进来,来减少享元类被实例化的数目,减少系统消耗

    1.网页游戏刷屏怪物

      千万怪物灵魂,来到轮回工厂。工厂将灵魂放入生产线,赋予种族模板和皮肤模板(假设一款游戏,有3种怪物,每一种怪物样子都一样,boss和小怪只有皮肤颜色不同。如果怪物的属性是名字、样子和皮肤颜色,那么我们实例化一只怪物的时候,同时需要实例化一次样子和皮肤。数量少的话,还无所谓,一旦要实例化10W、100W只怪物的话,我们就需要实例化10W、100W次样子和皮肤,系统承担很大的内存消耗。通过观察,怪物的样子数量是固定的,皮肤颜色也是固定的,我们可以将这两个属性共享出去,这样实例化怪物的时候,就减少了样子和皮肤的实例化对象数量)

      定义享元类的超类或者接口,可以接受或者作用于外部状态

        /// <summary>
        /// 具体享元类的超类或者接口(可以接受或者作用于外部状态)
        /// </summary>
        public abstract class Flyweight
        {
            /// <summary>
            /// 颜色(内部状态)
            /// </summary>
            public string Colour { get; set; }
    
            /// <summary>
            /// 种类(内部状态)
            /// </summary>
            public string Kind { get; set; }
    
            /// <summary>
            /// 操作flyweight使用者
            /// </summary>
            /// <param name="name">flyweight使用者(外部状态)</param>
            public abstract void Operation(string obj);
        }
    

       定义怪物模型,具体的享元类,为内部状态增加存储空间

        /// <summary>
        /// 怪物模型类(具体享元类,为内部状态增加存储空间)
        /// </summary>
        public class MonsterModel : Flyweight
        {
            /// <summary>
            /// 给怪物灵魂赋予种族和皮肤
            /// </summary>
            /// <param name="obj">怪物灵魂</param>
            public override void Operation(string obj)
            {
                Console.WriteLine("{0},系统大神赋予了我{1}种族的样子和{2}的皮肤,哇咔咔~我来了,菜鸟们~", obj, this.Kind, this.Colour);
            }
        }
    

       定义享元工厂,用来创建和管理享元对象。确保合理的共享享元对象,当用户请求一个享元对象时,工厂提供一个已创建的或者创建一个(如果不存在的话),这里可以同单例模式一起使用

        /// <summary>
        /// 享元工厂(用来创建和管理享元对象。确保合理的共享享元对象,当用户请求一个享元对象时,工厂提供一个已创建的实例或创建一个(如果不存在的话))
        /// </summary>
        public class FlyweightFactory
        {
            public Hashtable flyweights = new Hashtable();
    
            public FlyweightFactory()
            {
                flyweights.Add("白色史莱姆", new MonsterModel() { Kind = "史莱姆", Colour = "白色" });
                flyweights.Add("蓝色史莱姆", new MonsterModel() { Kind = "史莱姆", Colour = "蓝色" });
                flyweights.Add("紫色史莱姆", new MonsterModel() { Kind = "史莱姆", Colour = "紫色" });
            }
    
            public Flyweight GetFlyweight(string key)
            {
                return (Flyweight)flyweights[key];
            }
        }
    

       开启场景模拟

            static void Main(string[] args)
            {
                //千万怪物灵魂
                string model = "我是万千怪物灵魂中的{0}号";
    
                //来到轮回工厂
                FlyweightFactory factory = new FlyweightFactory();
    
                //工厂将灵魂放入生产线
                for (int n = 0; n < 10; n++)
                {
                    //赋予种族模板和皮肤模板
                    factory.GetFlyweight("白色史莱姆").Operation(string.Format(model, n));
                }
            }
    
  • 相关阅读:
    Blender文档翻译-Blender库数据的通用属性
    Blender文档翻译-什么是Ghash?
    PythonQt
    QT与Python混合编程经验记录
    WebStorm开发ReactNative过程中导入插件设置智能提示
    原生iOS项目导入ReactNative,各种问题
    关于网易七鱼iOS 端集成
    iOS "_OBJC_CLASS_$_JPUSHService", referenced from: 解决办法
    同时安装使用 两个Xcode切换的一些问题。
    实现一个iOS项目中添加多个target,并制作马甲包。
  • 原文地址:https://www.cnblogs.com/amywechat/p/4939505.html
Copyright © 2020-2023  润新知