[设计模式Java实现附plantuml源码~创建型] 确保对象的唯一性~单例模式

这篇具有很好参考价值的文章主要介绍了[设计模式Java实现附plantuml源码~创建型] 确保对象的唯一性~单例模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:
为什么之前写过Golang 版的设计模式,还在重新写Java 版?
答:因为对于我而言,当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言,更适合用于学习设计模式。
为什么类图要附上uml
因为很多人学习有做笔记的习惯,如果单纯的只是放一张图片,那么学习者也只能复制一张图片,可复用性较低,附上uml,方便有新理解时,快速出新图。


🔥[设计模式Java实现附plantuml源码]专链

  1. 确保对象的唯一性~单例模式
  2. 集中式工厂的实现~简单工厂模式
  3. 多态工厂的实现——工厂方法模式
  4. 产品族的创建——抽象工厂模式
  5. 对象的克隆~原型模式
  6. 复杂对象的组装与创建——建造者模式

饿汉单例

[设计模式Java实现附plantuml源码~创建型] 确保对象的唯一性~单例模式,设计模式,设计模式,java,单例模式

@startuml
class Singleton {
  - static instance = new Singleton
  + static getInstance(): Singleton
  + operation(): void
}
Singleton --> Singleton : getInstance()
@enduml

懒汉单例

[设计模式Java实现附plantuml源码~创建型] 确保对象的唯一性~单例模式,设计模式,设计模式,java,单例模式

@startuml
class Singleton {
  - static instance = null
  - constructor: Singleton
  + static getInstance(): Singleton
  + operation(): void
}
Singleton --> Singleton : getInstance()
@enduml

  • 懒汉加锁
    [设计模式Java实现附plantuml源码~创建型] 确保对象的唯一性~单例模式,设计模式,设计模式,java,单例模式
@startuml
class Singleton {
  - static volatile instance = null
  - constructor: Singleton
  + static getInstance(): synchronized Singleton
  + operation(): void
}
note left of Singleton::getInstance
if (instance == null)
	instance = construct();
return instance;
end note
Singleton --> Singleton : getInstance()
@enduml
  • 懒汉双重检测
    [设计模式Java实现附plantuml源码~创建型] 确保对象的唯一性~单例模式,设计模式,设计模式,java,单例模式
@startuml
class Singleton {
  - static volatile instance = null
  - constructor: Singleton
  + static getInstance(): synchronized Singleton
  + operation(): void
}
note left of Singleton::getInstance
// 一重检测
if (instance == null){
		synchronized(..) {
//	二重检测
				if(instance == null) {
							instance = construct();
				}
		}
}
return instance;
end note
Singleton --> Singleton : getInstance()
@enduml

代码实现

饿汉
public class EagerSingleton {
    private static final EagerSingleton instance = new EagerSingleton();

    // 私有构造方法,防止外部实例化
    private EagerSingleton() {
    }

    // 获取单例对象的静态方法
    public static EagerSingleton getInstance() {
        return instance;
    }
}

EagerSingleton 类的构造方法被声明为私有,以防止外部通过 new 关键字实例化该类。而类中定义了一个私有静态变量 instance,它在类加载的时候就被创建并初始化为 EagerSingleton 类的一个实例。
getInstance() 方法是获取单例对象的静态方法,它直接返回了已经创建好的 instance 对象。
由于饿汉单例在类加载的时候就创建了对象,因此它具有线程安全的特性,但可能会造成一定的资源浪费,因为无论是否使用该单例对象,都会被提前创建。

懒汉单锁
public class LazySingleton {
    private static LazySingleton instance;

    // 私有构造方法,防止外部实例化
    private LazySingleton() {
    }

    // 获取单例对象的静态方法,使用synchronized关键字实现线程安全
    public static synchronized LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}
懒汉双重检测
public class LazySingleton {
    private static volatile LazySingleton instance;

    // 私有构造方法,防止外部实例化
    private LazySingleton() {
    }

    // 获取单例对象的静态方法,使用双重检测实现延迟加载和线程安全
    public static LazySingleton getInstance() {
        if (instance == null) {
            synchronized (LazySingleton.class) {
                if (instance == null) {
                    instance = new LazySingleton();
                }
            }
        }
        return instance;
    }
}

在上面的代码中,LazySingleton 类的构造方法被声明为私有,以防止外部通过 new 关键字实例化该类。类中定义了一个私有静态变量 instance,它在第一次调用 getInstance() 方法时才会被创建并初始化为 LazySingleton 类的一个实例。
getInstance() 方法是获取单例对象的静态方法。在方法中,首先检查 instance 是否为空,如果为空则进入同步代码块。在同步代码块内部,再次检查 instance 是否为空,这是为了防止多个线程同时通过了第一个检查而进入同步块,从而创建多个实例。如果 instance 仍然为空,则创建新的实例并将其赋值给 instance
使用 volatile 关键字修饰 instance 变量可以保证变量的可见性,从而避免在多线程环境下出现问题。
懒汉双重检测通过双重检查和同步块的方式实现了延迟加载和线程安全,同时也提高了性能。因此,它是一种常见的单例模式实现方式。


饿汉式单例类不能实现延迟加载,不管将来用不用,它始终占据内存;
懒汉式单例类线程安全控制烦琐,而且性能受影响。
可见,无论是饿汉式单例还是懒汉式单例都存在这样那样的问题。
有没有一种方法,能够将两种单例的缺点都克服,而将两者的优点合二为一呢?答案是肯定的。下面来学习这种更好的被称为 Initialization on Demand Holder(IoDH) 的技术。实现 IoDH 时,需在单例类中增加一个静态 (static) 内部类,在该内部类中创建单例对象,再将该单例对象通过 getInstance() 方法返回给外部使用

IODH实现懒汉模式
public class LazySingleton {
    private static class SingletonHolder {
        private static final LazySingleton instance = new LazySingleton();
    }

    // 私有构造方法,防止外部实例化
    private LazySingleton() {
    }

    // 获取单例对象的静态方法
    public static LazySingleton getInstance() {
        return SingletonHolder.instance;
    }
}

在上面的代码中,LazySingleton 类内部定义了一个私有静态内部类 SingletonHolder。在 SingletonHolder 内部,定义了一个私有静态变量 instance,它是 LazySingleton 类的一个实例。
由于静态内部类 SingletonHolder 只有在 getInstance() 方法被调用时才会被加载,所以在类加载的过程中并不会创建 instance 对象。只有当第一次调用 getInstance() 方法时,SingletonHolder 类会被加载,从而创建并初始化 instance 对象。这种方式利用了 Java 类加载的线程安全性和延迟加载的特性,实现了懒汉模式。
因此,通过 IODH 实现懒汉模式,可以在需要时延迟创建单例对象,并且保证了线程安全性。

单例模式总结

单例模式作为一种目标明确、结构简单、理解容易的设计模式,在软件开发中使用频率相当高,在很多应用软件和框架中都得以广泛应用。

1.主要优点单例模式的主要优点如下:

(1)单例模式提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它。
(2)由于在系统内存中只存在一个对象,因此可以节约系统资源。对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统的性能。(3)允许可变数目的实例。基于单例模式,开发人员可以进行扩展,使用与控制单例对象相似的方法来获得指定个数的实例对象,既节省系统资源,又解决了由于单例对象共享过多有损性能的问题。(注:自行提供指定数目实例对象的类可称之为多例类。)

单例模式的主要缺点如下:

(1)由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。
(2)单例类的职责过重,在一定程度上违背了单一职责原则。因为单例类既提供了业务方法,又提供了创建对象的方法(工厂方法),将对象的创建和对象本身的功能耦合在一起。
(3)现在很多面向对象语言(如Java、C#)的运行环境都提供了自动垃圾回收技术,因此,如果实例化的共享对象长时间不被利用,系统会认为它是垃圾,会自动销毁并回收资源,下次利用时又将重新实例化,这将导致共享的单例对象状态的丢失。

3.适用场景在以下情况下可以考虑使用单例模式:

(1)系统只需要一个实例对象。例如,系统要求提供一个唯一的序列号生成器或资源管理器,或者需要考虑资源消耗太大而只允许创建一个对象。
(2)客户调用类的单个实例只允许使用一个公共访问点。除了该公共访问点,不能通过其他途径访问该实例。文章来源地址https://www.toymoban.com/news/detail-805493.html

到了这里,关于[设计模式Java实现附plantuml源码~创建型] 确保对象的唯一性~单例模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • java 设计模式--创建者模式

    java 设计模式--创建者模式

    参考:Java常见设计模式总结 概念理解一 :将复杂对象的创建过程分解在不同的方法中,不同的创建过程组装成不同对象。对象的创建与产品本身分离开,使得对象的创建过程更加清晰。例如:旅游套餐售卖场景。 一个套餐大概会由机票、车票、酒店、景点门票组成。 套餐

    2024年02月10日
    浏览(9)
  • 【Java 设计模式】创建型之工厂方法模式

    【Java 设计模式】创建型之工厂方法模式

    在软件开发中,工厂方法模式是一种常见的创建型设计模式, 它提供了一种将对象的实例化延迟到子类的方法 。工厂方法模式通过定义一个创建对象的接口,但是让子类决定实例化哪个类。在本文中,我们将介绍 Java 设计模式中的工厂方法模式,了解其定义、使用场景以及

    2024年01月17日
    浏览(11)
  • 【Java 设计模式】创建型之建造者模式

    【Java 设计模式】创建型之建造者模式

    在软件开发中,建造者模式是一种创建型设计模式, 它将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示 。建造者模式通常包括一个指导者(Director)类和多个建造者(Builder)类,指导者负责组织建造者的构建过程,而建造者负责具体的构建步

    2024年01月21日
    浏览(12)
  • 【Java 设计模式】创建型之抽象工厂模式

    【Java 设计模式】创建型之抽象工厂模式

    在软件开发中,抽象工厂模式是一种常见的创建型设计模式, 它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类 。抽象工厂模式的核心思想是将一组相关的产品组合成一个工厂,客户端通过工厂接口创建一系列产品。在本文中,我们将介绍 Jav

    2024年01月17日
    浏览(19)
  • 【Java 设计模式】创建型之单例模式

    【Java 设计模式】创建型之单例模式

    在软件开发中,单例模式是一种常见的设计模式, 它确保一个类只有一个实例,并提供一个全局访问点 。单例模式在需要控制某些资源,如数据库连接池、线程池等共享资源的情况下非常有用。在本文中,我们将介绍 Java 设计模式中的单例模式,了解其实现方式、使用场景

    2024年01月18日
    浏览(14)
  • Java23种设计模式-创建型模式之单例模式

    单例模式 (Singleton Pattern):通过单例模式的方法创建的 类在当前进程中只有一个实例 (根据需要,也有可能一个线程中属于单例,如:仅线程上下文内使用同一个实例),该类负责 创建自己的对象 ,同时 确保只有单个对象 被创建。 注 : 1、单例类 只能 有 一个实例 。

    2024年04月26日
    浏览(19)
  • 24种设计模式之创建者模式-Java版

    24种设计模式之创建者模式-Java版

    软件设计模式是前辈们代码设计经验的总结,可以反复使用。设计模式共分为3大类,创建者模式(6种)、结构型模式(7种)、行为型模式(11种),一共24种设计模式,软件设计一般需要满足7大基本原则。下面通过5章的学习一起来看看设计模式的魅力吧。 创建型模式(6种):本质上就

    2024年01月22日
    浏览(9)
  • 【Design Pattern 23种经典设计模式源码大全】C/Java/Go/JS/Python/TS等不同语言实现

    【Design Pattern 23种经典设计模式源码大全】C/Java/Go/JS/Python/TS等不同语言实现

    经典设计模式源码详解,用不同语言来实现,包括Java/JS/Python/TypeScript/Go等。结合实际场景,充分注释说明,每一行代码都经过检验,确保可靠。 设计模式是一个程序员进阶高级的必然选择,不懂设计模式,就像写文章不懂得层次,盖房子没有结构。只有充分懂得设计之道,

    2023年04月11日
    浏览(14)
  • 设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的

    设计模式 代理模式(静态代理 动态代理) 与 Spring Aop源码分析 具体是如何创建Aop代理的

    代理模式是一种结构型设计模式,它通过创建一个代理对象来控制对真实对象的访问。这种模式可以用于提供额外的功能操作,或者扩展目标对象的功能。 在代理模式中,代理对象与真实对象实现相同的接口,以便在任何地方都可以使用相同的接口来调用真实对象的方法。这

    2024年01月20日
    浏览(13)
  • 【java设计模式】创建型模式介绍(工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式)

    简介 本文介绍Java设计模式中创建型模式的五种 一、工厂模式 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 工厂模式提供了一种将对象的实例化过程封装在工厂类中的方式。通过使用工

    2024年02月16日
    浏览(17)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包