使用机制:
确保類只會被创建一个对象,一般會提供一个全局访问点讓程序可访问该对象,通常使用於共享资源的并行访问之控制,如常見於日志记录、数据库操作、印表机后台处理程序之場合中,此處值得一提的是Python所有的模块也都是採用单例模式使用於應用程序開發中。
示例:
# encoding: utf-8
class Singleton(object): #单例模式之类設計
@classmethod
def __new__(cls): #创建實例化對象前會優先调用__new__()方法,此處cls代表本類別,表示後續要使用此參數進行相關設定
if not hasattr(cls,"instance"): #判断是否存在instance属性
cls.instance = super(Singleton,cls).__new__(cls) #super(Singleton, cls)指繼承object 之意
# print(cls.instance)
return cls.instance
class Singleton2(object): #一般类(*此非单例類)
pass
#使用单例模式创建两个类
s0 = Singleton()
print ("Object created", s0) #此會打印s0物件(*即__main__.Singleton)在內存之參考位置(*即id(s0))
s1 = Singleton()
print ("Object created", s1)
#使用一般類创建两个类
s2 = Singleton2()
print ("Object created", s2)
s3 = Singleton2()
print ("Object created", s3)
输出並比對結果:
('Object created', <__main__.Singleton object at 0x02598250>)
('Object created', <__main__.Singleton object at 0x02598250>)
('Object created', <__main__.Singleton2 object at 0x02598270>)
('Object created', <__main__.Singleton2 object at 0x02598290>)
懒汉式单例模式
特性:保证要使用时才创建对象,此可預防导入單例模块後若没有使用而造成內存的浪费。
示例:
# encoding: utf-8
class Singleton:
__instance = None #此屬性是自定義非編程語言內定之預設值
def __init__(self): #注:此初始化不會真正作创建實例化之過程
if not self.__instance:
print ("__init__ method is called..")
else:
print ("Instance already created:",self.getInstance())
@classmethod
def getInstance(cls):
if not cls.__instance :
cls.__instance= Singleton() #注:此步驟才具创建實例化之過程
return cls.__instance
s = Singleton() #注意:此雖進入初始化但沒進行實例化之创建過程
print("Object created", Singleton.getInstance()) #當要實例化對象則需調用類別方法來進行真正實例化過程
s1 = Singleton() #因實例已存在,故不會再新建
print("Object created", Singleton.getInstance()) #調用已存在之實例
輸出並比對:
__init__ method is called..
__init__ method is called..
Object created <__main__.Singleton object at 0x000002B0EFA85438>
Instance already created: <__main__.Singleton object at 0x000002B0EFA85438>
Object created <__main__.Singleton object at 0x000002B0EFA85438>
单例模式之變形:單態(Monostate)
特性:不同对象但共享相同状态。
示例:
# encoding: utf-8
class Borg:
__shared_state = {"1":"2"}
def __init__(self):
self.x = 1
self.__dict__ = self.__shared_state
pass
b = Borg()
b1 = Borg()
b.x = 4
print ("Borg Object 'b': ",b) # b和b1不是同一个对象
print ("Borg Object 'b1': ",b1)
print ("Borg State 'b': ",b.__dict__) #但b和b1共享状态
print ("Borg State 'b1': ",b1.__dict__)
輸出並比對:
Borg Object 'b': <__main__.Borg object at 0x000002D6BCCA4F98>
Borg Object 'b1': <__main__.Borg object at 0x000002D6BCCB40F0>
Borg State 'b': {'1': '2', 'x': 4}
Borg State 'b1': {'1': '2', 'x': 4}
单例模式的优缺点
- 优点:可减少资源的过度使用,常見之應用:如线程池、缓存等
- 缺点:由於單例模式的全局变量是全局数据,故牽一髮而動全身。