游戏编程模式|不要让单例在代码中泛滥

单例模式简述


“确保一个类只有一个实例,并为其提供一个全局访问入口”。
单例模式不仅描述非常简单,代码也非常好写,类似这样:

class Singleton {
public:
    static public Singleton* getInstance(){
        if (instance == NULL){
            instance = new Singleton();
        }
        return instance;
    }
private:
    Singleton(){}
    static Singleton* instance;
}

单例模式确实带给了我们极大的方便,有些情况下,一个类有多个实例就不能正常工作。
比如一个操作文件的类,为了保证各步操作不互相干扰,我们封装的类就必须知道每步调用的操作,如果这个类有多个实例,那么我们就无法获知其他实例的操作。

被玩坏的单例


现在,我学会了一个很好的模式,我一定要在实际编程中使用它~
然后,灾难就来了:我需要一个XXX管理器,在游戏的很多地方都要使用它,对了,使用单例模式就轻松解决了!
于是,在代码中就充满了单例,然而,单例一时爽,却有很多隐患。

虽然有单例模式这种看起来高端一些的名字,实际上,单例模式就是一个全局变量,全局变量的危害许多人都非常了解,但是套上了一层设计模式的面纱,就把它抛之脑后了,美其名曰:我再使用单例模式写代码。但是,随着游戏变得更大更复杂,这样的全局变量就会带来很多危害:

  1. 它们令代码晦涩难懂。假设我们正在跟踪其他人写的函数中的bug。如果这个函数没有使用全局状态,那么我们只需要将精力集中在理解函数体,和传递给它的参数就可以了。
  1. 全局变量促进了耦合。全局变量使得任何人都可以轻松的使用它,在一个不了解结构的新手完成开发任务时,很可能为了完成任务,使得本不应该产生耦合的地方使用了这个单例。
  2. 它对并发不友好。当设置全局变量时,我们创建了一段内存,每个线程都能访问和修改它,而不管它们是否知道其他线程正在操作它。这有可能导致死锁、条件竞争和其他一些难以修复的线程同步的bug。

难以控制的单例


如果你的单例会在需要的时候创建,会出现这样的问题:你无法得知单例创建的时间。

当你实例化一个游戏系统的时候,可能会花费较长的时间,作为用户,肯定不希望在玩游戏玩得正嗨的时候遇到卡顿和掉帧,因此,比较好的方法是在加载游戏的时候手动控制单例的初始化。

你还需要小心翼翼的处理单例初始化的顺序(如果某个单例与另一个单例存在耦合,当然,不存在耦合是最好的,然而,当系统非常庞大的时候,你很难保证这一点),让你的系统能够正常的运行。

LZ在做的游戏中有个读取配置的单例系统,在做另一个单例系统的功能的时候,又依赖这个读取配置的单例。悲剧的是,在退出游戏到登录界面的时候,会把原来的系统干掉,重新读取配置,然而,另一个单例却依然存在,在某些特殊的情况下,调用这个功能的时候,程序就会崩溃掉。
因此,LZ不得不将两个系统的生命周期理顺,在当时临近发版本不能发生大的改动的情况下,只能加上很多check的代码防止崩溃。
虽然这个例子中的情况并不会很常见,但LZ想说的是,这个系统本来就可以不用单例的方式编写,当你能很好的控制这个实例的生命周期的时候,以上出现的各种奇怪的问题就不会出现了。单例用起来简单,可是它会一步一步将你的系统变得更见复杂和难以管理,留下许多暗坑。因此,在你想使用单例的时候,最好想一想,是否一定需要这样处理。

Other


当然,完全不使用单例也不是很现实。单例依然很强大并实用,在使用中,始终保持谨慎是很重要的,在最需要的地方使用,而抛弃那些可有可无的方案,不让单例模式在代码中泛滥,会让程序更加健壮~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 单例模式(SingletonPattern)一般被认为是最简单、最易理解的设计模式,也因为它的简洁易懂,是项目中最...
    成热了阅读 4,304评论 4 34
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,944评论 25 709
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,087评论 19 139
  • 我就觉得应该有什么大事要发生 头条新闻,成都发声了 审图必须应用BIM,否则不得通过! 好严肃啊,辣么任性? 但是...
    图驴阅读 2,060评论 0 1
  • 2017.6.12 星期一 雨转多云亲子日记 (50) 马上中学考完小学就要考试了,所以孩子们就要加油复习知识了。...
    于泽妈妈阅读 207评论 0 0