单例模式
简介
单例模式是一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点,即全局只创建一个实例对象。
例子
class Car:
__instance = None # 代表实例对象
__flag = False # 是否赋值
def __new__(cls, *args, **kwargs):
if cls.__instance == None:
cls.__instance = super().__new__(cls)
return cls.__instance
def __init__(self, brand, color, wnumber):
if self.__flag == False:
self.brand = brand
self.color = color
self.wnumber = wnumber
self.__flag = True
def __str__(self):
return f'{self.brand}-{self.color}-{self.wnumber}'
@classmethod
def get_instance(cls):
return cls.__instance
# 只需创建一次
Car('玛莎拉蒂', '粉色', 18)
Car('小米su7', '冰蓝色', 18)
Car('迈巴赫', '黑色', 18)
# 任何位置都可以使用类来获得该单例对象!!
print(Car.get_instance())
打印如下图:
单例模式的优缺点
优点:
- 控制实例化:单例模式可以控制实例化的数量,确保系统中只有一个实例,这在资源有限或者需要统一管理的情况下非常有用。
- 全局访问点:提供一个全局访问点,使得可以从任何地方访问该实例,方便了对象的调用。
- 减少资源消耗:由于只有一个实例,可以节省资源,特别是对于重量级的对象,减少内存的使用。
- 共享状态:单例模式可以用来管理共享状态,例如数据库连接或者线程池。
- 简化代码:在某些情况下,单例模式可以简化代码,因为不需要每次使用时都创建和销毁对象。
缺点:
- 违反单一职责原则:单例类除了自身的业务逻辑外,还需要负责控制实例的创建,这违反了单一职责原则。
- 全局变量风险:单例模式实际上是一个全局变量,它可能会导致代码的耦合度增加,使得代码更难以测试和维护。
- 难以扩展:单例模式不适用于需要扩展的情况,因为它是固定的单例,不支持多实例。
- 线程安全问题:在多线程环境下,单例的创建可能会出现问题,需要额外的同步机制来保证线程安全。
- 可能导致懒加载失效:如果单例类在加载时就创建了实例(饿汉式),而不是在第一次使用时创建(懒汉式),那么可能会造成资源浪费。
- 难以模拟:在单元测试中,单例模式可能会难以模拟或者替换,因为它通常涉及到静态方法和类变量。
单例模式适合应用场景
单例模式适用于以下场景:
- 当系统中需要一个类来控制资源的访问,确保资源不被重复创建时。
- 当一个类需要频繁实例化,而实例化过程又非常耗时时。
- 当一个类需要被所有其他类访问,但又不希望产生多个实例时。