单例模式

Singleton Pattern

创建型模式

📖 模式定义

单例模式确保一个类只有一个实例,并提供一个全局访问点来获取该实例。这种模式在需要控制资源访问、协调系统行为或确保某些组件只有一个副本时非常有用。

🎯 解决的问题

💻 代码实现

Java 实现(线程安全的懒汉式)

Java
public class Singleton {
    // 使用 volatile 关键字确保多线程环境下的可见性
    private static volatile Singleton instance;
    
    // 私有构造函数,防止外部实例化
    private Singleton() {
        // 防止反射攻击
        if (instance != null) {
            throw new RuntimeException("请使用 getInstance() 方法获取实例");
        }
    }
    
    // 双重检查锁定(Double-Checked Locking)
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
    
    // 业务方法
    public void doSomething() {
        System.out.println("单例对象正在执行业务逻辑...");
    }
}

Python 实现(装饰器方式)

Python
def singleton(cls):
    """单例装饰器"""
    instances = {}
    
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    
    return get_instance

@singleton
class DatabaseConnection:
    def __init__(self):
        self.connection = None
        print("创建数据库连接...")
    
    def connect(self):
        if not self.connection:
            self.connection = "已连接到数据库"
        return self.connection
    
    def query(self, sql):
        return f"执行查询: {sql}"

# 使用示例
db1 = DatabaseConnection()
db2 = DatabaseConnection()
print(db1 is db2)  # True,同一个实例

JavaScript 实现(ES6 类)

JavaScript
class Singleton {
    constructor() {
        // 如果已经存在实例,返回现有实例
        if (Singleton.instance) {
            return Singleton.instance;
        }
        
        // 初始化实例
        this.data = [];
        this.timestamp = Date.now();
        
        // 保存实例引用
        Singleton.instance = this;
        
        // 冻结实例,防止修改
        Object.freeze(this);
    }
    
    addData(item) {
        this.data.push(item);
    }
    
    getData() {
        return this.data;
    }
    
    static getInstance() {
        if (!Singleton.instance) {
            Singleton.instance = new Singleton();
        }
        return Singleton.instance;
    }
}

// 使用示例
const instance1 = new Singleton();
const instance2 = new Singleton();
const instance3 = Singleton.getInstance();

console.log(instance1 === instance2); // true
console.log(instance1 === instance3); // true

✅ 优点

  • 控制实例数量:确保类只有一个实例
  • 全局访问:提供全局访问点
  • 延迟初始化:可以在需要时才创建实例
  • 节省资源:避免重复创建昂贵的对象
  • 状态一致性:确保全局状态的一致性

❌ 缺点

  • 违反单一职责:既要管理实例创建又要处理业务逻辑
  • 难以测试:全局状态使单元测试变得困难
  • 隐藏依赖:代码依赖关系不够明确
  • 线程安全:多线程环境下需要特殊处理
  • 扩展困难:难以继承和扩展

🔧 适用场景

⚠️ 注意事项

🔄 相关模式