【设计模式】单例模式

设计模式的分类:

        创建型模式:这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。

        工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式

        结构型模式:这些模式关注对象之间的组合和关系,旨在解决如何构建灵活且可复用的类和对象结构。

        适配器模式、桥接模式、过滤器模式、组合模式、装饰器模式、外观模式、享元模式、代理模式

        行为型模式:这些模式关注对象之间的通信和交互,旨在解决对象之间的责任分配和算法的封装。

        责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、空对象模式、策略模式、模板模式、访问者模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。主要解决的是频繁创建和销毁全局使用的类实例的问题。

优点:

  • 内存中只有一个实例,减少内存开销,尤其是频繁创建和销毁实例时(如管理学院首页页面缓存)。
  • 避免资源的多重占用(如写文件操作)。

缺点:

  • 没有接口,不能继承。
  • 与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心实例化方式。

结构:

单例模式包含以下几个主要角色:

  • 单例类:包含单例实例的类,通常将构造函数声明为私有。
  • 静态成员变量:用于存储单例实例的静态成员变量。
  • 获取实例方法:静态方法,用于获取单例实例。
  • 私有构造函数:防止外部直接实例化单例类。
  • 线程安全处理:确保在多线程环境下单例实例的创建是安全的。

实现方式:懒汉式、饿汉式、双重锁校验、静态内部类、枚举

懒汉式:懒汉式单例模式是最简单的实现方式,它在第一次被请求时才创建实例。这种方式的特点是简单,但存在线程安全问题。

优点:节省资源,只有在需要时才创建实例

缺点:

  • 线程不安全,在多线程环境下,可能会产生多个实例。
  • 每次调用getInstance()方法时都需要进行同步,可能会影响性能。

适用场景:单线程环境、不考虑资源消耗

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 Singleton instance = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return instance;
    }
}

双重锁校验:双重检查锁定是一种在懒汉式基础上增加线程安全的方法。它首先检查实例是否已经创建,如果未创建,则通过同步代码块创建实例。

优点:

  • 节省资源:只有在需要时才创建实例。
  • 线程安全:通过双重检查和同步代码块确保单例的唯一性。

缺点:

  • 复杂性:实现比前两种方式复杂。
  • 存在内存一致性问题:需要使用volatile关键字确保内存可见性。

适用场景:多线程环境;需要在需要时才创建实例,同时保证线程安全。

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;
    }
}

静态内部类:静态内部类是一种通过Java语言本身的特性实现单例模式的方法。这种方式利用了Java的类加载机制来保证线程安全。

优点:

  • 线程安全:利用Java的类加载机制,确保单例的唯一性。
  • 延迟加载:只有在第一次调用getInstance()方法时才加载静态内部类,从而延迟实例的创建。

缺点:资源消耗:尽管延迟加载,但静态内部类的存在可能会占用一定的内存。

适用场景:多线程环境;需要延迟加载单例对象

public class Singleton {
    private Singleton() {}

    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

枚举:使用枚举实现单例模式是一种简单且线程安全的方式。Java语言规范保证每个枚举常量只会被实例化一次。

优点:

  • 线程安全:Java语言规范保证枚举常量的唯一性。
  • 简单:实现简单,易于理解和维护。
  • 自动支持序列化机制:枚举类型是单例的天然实现。

缺点:灵活性较差:枚举类型不支持继承,扩展性较差。

适用场景:需要单例对象的场合,且对扩展性要求不高;需要序列化支持的场合。

public enum Singleton {
    INSTANCE;

    public void someMethod() {
        // 可以在这里添加一些方法
    }
}

总结

  • 懒汉式适合单线程环境或资源消耗不是主要考虑因素的场景。
  • 饿汉式适合多线程环境,且单例对象的创建成本不高或需要尽早初始化的场景。
  • 双重检查锁定适合多线程环境,需要在需要时才创建实例,同时保证线程安全的场景。
  • 静态内部类适合多线程环境,需要延迟加载单例对象的场景。
  • 枚举适合需要单例对象,且对扩展性要求不高的场景,同时支持序列化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值