参考:https://github.com/mohuishou/go-design-pattern/tree/master/01_singleton
什么是单例模式?
保证某个类在一个运行环境中只有一个实例, 并提供一个访问实例的全局节点;例如:mysql游标等,一个环境中必须保证只有一个。比如我们的APP中有一个类用来保存运行时全局的一些状态信息,如果这个类实现不是单例的,那么App里面的组件能够随意的生成多个类用来保存自己的状态,等于大家各玩各的,那这个全局的状态信息就成了笑话了。而如果把这个类实现成单例的,那么不管App的哪个组件获取到的都是同一个对象(比如Application类,除了多进程的情况下)。
Ensure a class has only one instance, and provide a global pointof access to it.
为什么要用到单例模式?
在软件设计中, 经常有一些特殊的类,需要保证在系统中只有唯一一个实例才能保证正确性和效率。
如何才算一个单例模式?
不管那种模式最终目的只有一个,就是只实例化一次,只允许一个实例存在。
懒汉式实现
这里我们使用三种方式实现饿汉模式。先说一下什么是懒汉模式吧,从懒汉这两个字,我们就能知道,这个人很懒,所以他不可能在未使用实例时就创建了对象,他肯定会在使用时才会创建实例,这个好处的就在于,只有在使用的时候才会创建该实例。下面我们一起来看看他的实现:
package singleton
import "sync"
var (
singleton *Singleton
once = &sync.Once{}
)
func GetInstance() *Singleton {
if singleton == nil {
once.Do(func() {
singleton = &Singleton{}
})
}
return singleton
}
饿汉式实现方式
什么是饿汉?
饿汉模式我们很好解释了,因为他饿呀,所以很着急的就创建了实例,不用等到使用时才创建,这样我们每次调用获取接口将不会重新创建新的对象,而是直接返回之前创建的对象。比较适用于:如果某个单例使用的次数少,并且创建单例消息的资源比较多,那么就需要实现单例的按需创建,这个时候懒汉模式就是一个不错的选择。不过也有缺点,饿汉模式将在包加载的时候就会创建单例对象,当程序中用不到该对象时,浪费了一部分空间,但是相对于懒汉模式,不需要进行了加锁操作,会更安全,但是会减慢启动速度。
package singleton
// Singleton 饿汉式单例
type Singleton struct{}
var singleton *Singleton
func init() {
singleton = &Singleton{}
}
// GetInstance 获取实例
func GetInstance() *Singleton {
return singleton
}