zoukankan      html  css  js  c++  java
  • 【Unity3D与23种设计模式】享元模式(Flyweight)

    GoF中定义:

    “使用共享的方式,让一大群小规模对象能更有效地运行”

    享元模式一般应用在游戏角色属性设置上

    游戏策划需要通过“公式计算”或者“实际测试”等方式找出最佳的游戏属性

    因此,在游戏系统中建立一个管理方式来建立和存储属性信息就显得尤为重要

    对象中那些只能读取不能写入的共享部分被称为“内在状态”

    如:最大生命(MaxHP)、移动速度(MoveSpeed)等属性

    还有不能被共享的部分,被称为“外部状态”

    如:当前生命(NowHP)、等级(LV)等属性

    享元模式提供的解决方案是:

    产生对象时,将能够共享的“内在状态”加以管理

    并且将属于各对象能自由更改的“外部状态”也一起设置给新产生的对象中

    //可以被共享的Flyweight接口
    public abstract class Flyweight {
        protected string m_Count;
    
        public Flyweight() { }
    
        public Flyweight(string Content)
        {
            m_Count = Content;
        }
    
        public string GetContent() {
            return m_Count;
        }
    
        public abstract void Opreator();
    }
    //共享的组件
    public class ConcreteFlyweight : Flyweight {
        public ConcreteFlyweight(string Content) : base(Content) { }
    
        public override void Opreator()
        {
            Debug.Log("ConcreteFlyweight.Content["+m_Count+"]");
        }
    }
    //不共享的组件
    public class UnsharedCoincreteFlyweight {
        Flyweight m_Flyweight = null;
        string m_UnsharedContent;
    
        public UnsharedCoincreteFlyweight(string Content) {
            m_UnsharedContent = Content;
        }
    
        public void SetFlyweight(Flyweight theFlyweight) {
            m_Flyweight = theFlyweight;
        }
    
        public void Operator() {
            string Msg = string.Format("UnsharedCoincreteFlyweight.Content[{0}]",m_UnsharedContent);
    
            if (m_Flyweight != null)
                Msg += "包含了:" + m_Flyweight.GetContent();
            Debug.Log(Msg);
        }
    }
    //产生Flyweight的工厂接口
    public class FlyweightFactor {
        Dictionary<string, Flyweight> m_Flyweights = new Dictionary<string, Flyweight>();
    
        public Flyweight GetFlyweight(string Key,string Content) {
            if (m_Flyweights.ContainsKey(Key)) {
                return m_Flyweights[Key];
            }
    
            ConcreteFlyweight theFlyweight = new ConcreteFlyweight(Content);
    
            m_Flyweights[Key] = theFlyweight;
            Debug.Log("New ConcreteFlyweight Key["+Key+"] Content["+ Content +"]");
            return theFlyweight;
        }
        public UnsharedCoincreteFlyweight GetUnsharedFlyweight(string Content) {
            return new UnsharedCoincreteFlyweight(Content);
        }
    
        public UnsharedCoincreteFlyweight GetUnsharedFlyweight(string Key, string SharedContent, string UnsharedContent) {
            Flyweight SharedFlyweight = GetFlyweight(Key,SharedContent);
    
            UnsharedCoincreteFlyweight theFlyweight = new UnsharedCoincreteFlyweight(UnsharedContent);
            theFlyweight.SetFlyweight(SharedFlyweight);
            return theFlyweight;
        }
    }
    //测试类
    void UnitTest() {
            FlyweightFactor theFactory = new FlyweightFactor();
    
            theFactory.GetFlyweight("1","共享组件1");
            theFactory.GetFlyweight("2","共享组件2");
            theFactory.GetFlyweight("3","共享组件3");
        }
    //输出信息
    New ConcreteFlyweight Key[1] Content[共享组件1]
    New ConcreteFlyweight Key[2] Content[共享组件2]
    New ConcreteFlyweight Key[3] Content[共享组件3]

    其他应用:

    游戏中某些不断创建销毁的物体,如子弹

    为了让游戏高效的管理这些数量庞大的物体

    可使用享元模式来建立子弹对象池(Object Pool)

    减少因为重复处理产生子弹对象、删除子弹对象所导致的性能损失。

    文章整理自书籍《设计模式与游戏完美开发》 菜升达 著

  • 相关阅读:
    pytest05-参数化
    pytest04-conftest配置文件
    pytest03-fixture
    pytest02-setup和teardown
    SimpleDateFormat 是线程不安全的类,一般不要定义为 static 变量,如果定义为 static ,必须加锁,或者使用 DateUtils 工具类
    线程池不使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式
    线程资源最好通过线程池提供
    获取单例对象需要保证线程安全,其中的方法也要保证线程安全
    高度注意 Map 类集合 K / V 能不能存储 null 值的情况,如下表格
    使用 entrySet 遍历 Map 类集合 KV ,而不是 keySet 方式进行遍历的好处
  • 原文地址:https://www.cnblogs.com/fws94/p/7245668.html
Copyright © 2011-2022 走看看