设计模式 —— 单例模式

目录

  • 概述
  • 实现
  • 优缺点

概述

单例模式是 创建型 设计模式的一种。让一个类只存在一个实例,也就是不允许其他人直接调用类,而是通过方法。

定义:确保一个类最多只有一个实例,并提供一个全局访问点

适用场景:例如平时的word文档,同时将一个文件打开两份进行修改会使得其中一份修改无效,所以不可以将一份文件打开为两份,在已经点开文件的同时在点击文件只会跳转到已打开的文件中。

实现

// 需要单例的类有两种实现方法:预加载和懒加载
// 预加载
public class PreloadSingleton{
    public static PreloadSingleton instance = new PreloadSingleton();
    // 提前将对象实例化,不允许其他类实例该对象
    private PreloadSingleton(){};
    
    public static PreloadSingleton getInstance(){
        return instance;
    }
}


//懒加载
public class Singleton {
    private static Singleton instance = null;
    
    private Singleton(){};
    
    // 不在一开始加载对象,减少系统开销,在第一次被调用时创建
    public static Singlrton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

优缺点

优点

  1. 全局访问点:单例模式提供了一个全局访问点,可以在程序的任何地方访问该实例,方便对实例的统一管理和调用。
  2. 节省资源:由于单例模式只创建一个实例并共享使用,可以节省系统资源,特别是在需要频繁创建和销毁对象时能够提高性能。
  3. 避免重复创建:通过单例模式可以确保一个类只有一个实例存在,避免了重复创建相同对象的情况,保证数据一致性。
  4. 懒加载:懒汉式单例模式在首次使用时才会初始化对象,延迟了对象的创建时间,提高了性能。
  5. 线程安全:合理设计单例模式可以确保在多线程环境下仍能保持实例的唯一性,避免出现竞态条件和数据不一致的情况。
  6. 控制实例个数:单例模式可以帮助开发人员限制类的实例化次数,确保符合业务逻辑或系统需求。

缺点

  1. 对扩展不友好:单例模式会在全局范围内引入全局状态,使得后续难以扩展和调试。如果需要在系统中引入多个实例或者子类化单例类,可能需要重构代码。
  2. 可能导致性能问题:在多线程环境下,常见的单例实现方式可能需要加锁来确保线程安全,这会降低性能。在某些情况下,单例模式可能成为性能瓶颈。
  3. 隐藏依赖关系:单例模式隐藏了类之间的依赖关系,增加了代码的耦合度,使得代码难以理解和维护。
  4. 不利于单元测试:单例模式的全局状态可能会影响单元测试的可靠性,因为测试很难隔离单例对象。
  5. 违反单一职责原则:单例模式同时扮演了创建对象和管理对象生命周期的角色,违反了单一职责原则,使得代码的功能划分不清晰。

预加载:只有return语句,可以保证线程安全,但是预加载会造成一定的内存浪费

懒加载:不浪费内存,便无法保证线程安全(if内存执行代码时非原子性的)且new Singleton()也无法保证执行的顺序性(初始化内存空间→初始化对象→设置对象指向内存地址)