确保类只有一个实例,并提供一个全局的访问点。
单例(Singleton)类声明了一个名为getInstance的方法来返回其所属类的一个相同实例。
单例的构造函数必须对客户端的代码隐藏。调用getInstance方法必须是获取单例对象的唯一方式。
你可以肯定,一个类只有一个实例。
有助于获得该实例的全局访问点。
仅在首次请求单例对象时对其进行初始化。
单例模式可以掩盖糟糕的设计。例如,当程序组件对彼此了解太多。
不是线程安全的,你写的代码要确保为所有线程只创建一个实例。
单例的客户端代码单元测试可能会比较困难, 因为许多测试框架以基于继承的方式创建模拟对象。 由于单例类的构造函数是私有的, 而且绝大部分语言无法重写静态方法, 所以你需要想出仔细考虑模拟单例的方法。 要么干脆不编写测试代码, 或者不使用单例模式。
这里我们分两个例子吧,一个是简单的单例实现,另外一个是解决异步情况可能会出现的问题
sample
type single struct{}
var normalSingleInstance *single
func getNormalSingle() *single {
if normalSingleInstance == nil {
fmt.Println("creating single instance")
normalSingleInstance = new(single)
} else {
fmt.Println("single instance already created")
}
return normalSingleInstance
}
func main() {
for i := 0; i < 10; i++ {
getNormalSingle()
}
}
输出:
creating single instance
single instance already created
single instance already created
single instance already created
single instance already created
single instance already created
single instance already created
single instance already created
single instance already created
single instance already created
multithread
type single struct{}
var lock = &sync.Mutex{}
var multiThreadSafeInstance *single
func getMultiThreadSafeInstance() *single {
if multiThreadSafeInstance == nil {
lock.Lock()
defer lock.Unlock()
if multiThreadSafeInstance == nil {
fmt.Println("creating multi-thread safe instance now.")
multiThreadSafeInstance = new(single)
} else {
fmt.Println("multi-thread safe instance already created.")
}
} else {
fmt.Println("multi-thread safe instance already created.")
}
return multiThreadSafeInstance
}
func main() {
for i := 0; i < 2; i++ {
go func() {
for j := 0; j < 5; j++ {
getMultiThreadSafeInstance()
}
}()
}
select {}
}
输出:
creating multi-thread safe instance now.
multi-thread safe instance already created.
multi-thread safe instance already created.
multi-thread safe instance already created.
multi-thread safe instance already created.
multi-thread safe instance already created.
multi-thread safe instance already created.
multi-thread safe instance already created.
multi-thread safe instance already created.
multi-thread safe instance already created.