在过去的几年开发生涯中,我接触了几门编程语言(C++, Objective-C,Swift,Java),除了第一门语言(C++)外,新学每一门语言都要买一本该语言和平台相关的设计模式书籍,这不,就看了好几本设计模式书籍了,为了以后在学习新语言时能由内而外得写好各个模式,就有了写此系列文章的想法。
作为系列的第一篇文章,从“最简单”的单例模式开始,尝试提取设计模式的本质,但看过与语言无关的设计模式书籍,若是太抽象,这文章也没有存在的意义,直接去看原著就行了,我就尽可能与语言相关,又尽可能与语言无关地来讲述。
评价单例模式的唯一标准是,确保只会出现一个实例,看起来很简单,但实现起来有几处注意点:
创建,不管怎么搞,只能创建一个。
线程安全,多线程并发的时候还是只能创建一个。
开始之前扯点别的,如果你接触过多种语言,你会发现,各种语言中流行的获取实例的方法名称有些不太一样:getSingleton(), getInstance(),sharedName,name等等,关于这点,如果你新上手一门语言要实现这个模式,如果你想看起来“比较有经验”可以参考对应语言大家都用的名称,用自己原来语言熟悉的名称也没有问题,别人看你代码的时候还能看出你原来是写啥语言的。
单例变量放在哪? 答案是static 变量里,或是局部静态变量或是静态成员变量、或是全局静态变量,在条件允许的情况下越里面越好,当然,还要使用语言各自的特性保证封装性,对外部隐藏实现,该private的private,有头文件源文件的就放源文件。
限制外部创建:最好的是从编译级别限制从外部创建,那就是将构造函数设置为私有,做不到的就次之,重载后内部调用实现的单例接口。针对OC MRC,个人认为这是实现单例最麻烦的一门语言,需要将一系列函数重载掉。这是语言特性,需要封堵掉全部能产生实例的方法以及相关副作用。
线程安全:使用语言特性,确保多线程时还是只有一个实例就行,根据经验,很多人在实践过程中会忽略限制外部创建和线程安全,也能工作,但这就不能叫单例了。
在实际使用的时候,我们通常用模板、宏等实现一劳永逸的效果。
该模式有个扩展,对象池模式,将可创建的数量设定为一个有限值。实现的时候,请仔细参考各个平台的成熟实现。
网友评论