目錄
- 概念理解
- 使用場景
- 優缺點
- 實現方式
概念理解
單例模式要保證一個類在整個系統運行期間,無論創建多少次該類的對象,始終只會有一個實例存在。就像操作系統中的任務管理器,無論何時何地調用它,都是同一個任務管理器在工作,不會同時出現多個不同的任務管理器實例
使用場景
- 資源共享:當多個模塊需要共享同一個資源時,使用單例模式可以避免資源的重復創建和浪費。例如,數據庫連接池,使用單例模式可以確保所有模塊使用的同一個數據庫連接池,避免了 多個連接池的創建,提高了資源的利用率
- 日志記錄器:在一個應用程序中,通常只需要一個日志記錄器來記錄系統的運行信息。使用單例模式可以確保所有模塊都使用同一個日志記錄器,避免了日志信息的分散和混亂
- 配置管理:在一個系統中,配置信息通常是全局的,并且只需要一份。使用單例模式中可以確保所有模塊都使用同一個配置對象,方便對配置信息進行統一管理和修改
優缺點
優點
- 節省資源:由于只創建一個實例,減少了系統資源的開銷,特別是對于一些創建和銷毀開銷較大的對象,如數據庫連接、文件系統等。
- 全局訪問:提供了一個全局訪問點,方便其他模塊獲取該實例,避免了在多個地方重復創建對象。
- 數據一致性:由于所有模塊都使用同一個實例,保證了數據的一致性和完整性。
缺點 - 違反單一職責原則:單例模式的類既負責創建實例,又負責管理實例的生命周期,違反了單一職責原則。
- 擴展性差:由于單例模式的類只有一個實例,難以進行擴展和修改。如果需要對單例類進行擴展,可能需要修改原有的代碼,不符合開閉原則。
- 多線程問題:在多線程環境下,如果沒有進行適當的同步處理,可能會導致多個線程同時創建實例,破壞單例模式的唯一性。
實現方式
懶漢式(線程不安全)
class Singleton:_instance = None@classmethoddef get_instance(cls):if cls._instance is None:cls._instance = cls()return cls._instance# 使用示例
s1 = Singleton.get_instance()
s2 = Singleton.get_instance()
print(s1 is s2) # 輸出: True
這種方式在第一次調用 get_instance 方法時才創建實例,但在多線程環境下可能會創建多個實例。
懶漢式(線程安全)
import threadingclass Singleton:_instance = None_lock = threading.Lock()@classmethoddef get_instance(cls):with cls._lock:if cls._instance is None:cls._instance = cls()return cls._instance# 使用示例
s1 = Singleton.get_instance()
s2 = Singleton.get_instance()
print(s1 is s2) # 輸出: True
通過加鎖的方式保證在多線程環境下也只會創建一個實例,但每次獲取實例都需要加鎖,會影響性能。
餓漢式
class Singleton:_instance = Nonedef __new__(cls, *args, **kwargs):if not cls._instance:cls._instance = super().__new__(cls, *args, **kwargs)return cls._instance# 使用示例
s1 = Singleton()
s2 = Singleton()
print(s1 is s2) # 輸出: True
這種方式在類加載時就創建實例,避免了多線程問題,但如果實例創建過程比較耗時,會影響系統的啟動性能。