logo
Zhanxin
Published on

设计模式之单例模式

Authors

定义

单例模式(Singleton),允许存在一个和仅存在一个给定类的实例,它提供一种机制让任何实体都可以访问该实例。


UML 图

代码实现

public class Singleton {
    private static Singleton _instance;
    private Singleton() {};

    public static Singleton getInstance() {
        if (null == _instance) {
            _instance = new Singleton();
        }
        return _instance;
    }
}
    1. 一个单例类只能有一个实例
    1. 单例类必须自行创建这个实例
    1. 单例类必须保证全局其他对象都能唯一访问到它

应对的变化

  1. 对象实例数量受到限制的事实
  2. 对象实例的构造与销毁
  3. 需要保证对象实例成为“线程安全”的某种机制

对象职责

  1. 保证一个类只有一个实例
  2. 为该实例提供一个全局访问节点 单例模式类似于全局变量或全局函数的角色,可以使用它来代替全局变量

常见场景和解决方案

ThreadLocal 会为每一个线程提供一个独立的对象副本,从而解决了多个线程对数据的访问冲突问题。

为什么使用

系统的某些资源有限

    1. 控制某些共享资源(例如,数据库或文件)的访问权限
    1. 同时读取同一个超大的 AI 模型文件,或使用外部进程式服务 需要表示为全局唯一的对象
    1. 系统要求提供一个唯一的序列号生成器

优势

    1. 对有限资源的合理利用,保护有限的资源,防止资源重复竞抢
    1. 更高内聚的代码组件,能提升代码复用性
    1. 具备全局唯一访问的权限控制,方便按照统一规则管控权限
    1. 从负载均衡角度考虑,可以轻松将 Singleton 扩展成两个,三个或更多个实例,由于封装了技术问题,所以在适当的时候可以自由更改实例的数量

劣势

    1. 作为全局变量使用时,引用的对象越多,代码修改影响的范围也越大
    1. 作为全局变量时,在全局变量中使用状态变量时,会造成加/解锁的性能损耗
    1. 即便能扩展多实例,但耦合性依然很高,因为隐蔽了不同对象之间的调用关系
    1. 不支持有参数的构造函数