单例模式(Singleton Pattern)用于确保一个类只有一个实例。
问题提出
单个实例我们经常见,比如学生宿舍共用唯一的一台洗衣机。但是,为什么我们需要保证类只有一个实例呢?
举例说明。某个应用程序有相关配置,利用Map来保存。
创建ConfigManager类,它有私有属性settings,set方法和get方法。
在Main类中,创建ConfigManager对象,添加某个配置,然后再创建另一个ConfigManager对象,读取刚才添加的配置。
很明显,我们用other对象是获取不到键为“name”的配置的,因为manager和other是不同的两个实例,而“name”只配置在manager对象里。
有时候需要将状态或数据保存在唯一的地方,就像这里,我们不能将应用程序的配置保存在多个地方。这就是我们需要使用单例模式的地方。
解决方案
当前是这样的结构。
要想实现ConfigManager类只有一个实例,需要做以下工作。
首先,将构造函数变成私有,这样的话就不能通过 new 操作符生成类的实例。
图中构造函数ConfigManager()前面的减号表示私有。
接着,类本身要负责创建这个单一的实例。添加静态私有属性instance,它是类的实例,它仅能被ConfigManager类本身访问。
最后,我们添加getInstance方法供外部获取这个单一实例,当然这个方法也必须是静态的。
下图中instance 和 getInstance的下划线表示它们是静态的。
这个就是单例模式(Singleton Pattern),它能确保类只有一个实例。
经典的四人帮的图如下。
代码实现
添加私有构造函数ConfigManager,函数体保持为空。这样外部比如Main类就无法通过 new ConfigManager()这样的语句来创建实例。
添加静态私有属性instance,并初始化一个实例,因为是在内部,可以使用new操作符。再给instance添加获取方法getInstance,自然它也是静态的。
在Main中,代替之前的new关键字,使用getInstance获取单一的实例。这样,我们任何时候获取的配置值都是一样的,因为都是同一个实例。
小结
单例模式(Singleton Pattern)可以确保一个类只有一个实例。