1、模式介绍:
单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点来访问该实例。在进行系统设计时,单例模式常用于需要共享状态或控制资源使用的场景。
2、应用场景:
数据库连接池、日志记录器和配置管理器等。
3、单例模式的优点:
唯一实例控制:
确保在整个应用程序中只有一个实例存在,避免了由于实例多次创建而导致的资源浪费和性能问题。
全局访问点:
提供一个全局访问点,可以在不同的模块或组件中轻松访问这个唯一的实例,简化了代码管理。
延迟初始化:
可以实现延迟加载,即在第一次使用时才创建实例,节省了资源,提高了程序启动速度。
线程安全:
可以通过适当的实现方式(如双重检查锁定、静态内部类等)确保线程安全,避免多线程环境下的实例重复创建问题。
控制资源使用:
适用于需要严格控制资源使用的场景,例如数据库连接、文件系统操作、网络通信等。
4、单例模式的缺点:
难以测试:
由于单例模式提供了一个全局实例,这使得在单元测试中很难进行模拟和隔离测试,从而增加了测试的复杂性。
隐藏的依赖性:
单例模式隐藏了类与类之间的依赖关系,使得代码更难理解和维护。使用全局访问点可能导致代码紧耦合,不利于模块化设计。
难以扩展:
单例模式限制了类的可扩展性,如果需要对单例类进行扩展或修改,可能需要重构大量代码。
生命周期控制复杂:
单例实例的生命周期与应用程序的生命周期绑定,如果不慎管理可能导致资源泄露或无法释放。
并发问题:
如果未能正确实现线程安全,单例模式在并发环境下会导致多个实例的创建,从而违背单例模式的初衷。
5、代码实现:
饿汉式(线程安全,但可能浪费资源)
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return INSTANCE;
}
}
懒汉式(线程不安全)
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
双重检查锁定(线程安全)
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
静态内部类(线程安全,推荐)
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
以上实现方式各有优缺点,选择合适的实现方式应根据具体应用场景的需求和约束条件。