抽丝剥茧 细说架构那些事——【优锐课】

单例模式可确保在给定的时间实例中只能创建一个具有全局访问点的对象。这是面向对象编程中最常用的技术之一。尽管它很简单,但从类设计的角度来看可能是最简单的,但是在尝试实现它们之前,必须先解决一些细微的问题。本文是在学习完优锐课JAVA架构VIP课程—【框架源码专题】中《学习源码中的优秀设计模式》后写下的学习感悟。通过引用Java代码示例来深入探索这种模式。

总览

在某些情况下,系统应在给定的时间点仅允许一个类的对象存储在内存中。这意味着,当程序实例化该对象时,不应允许该程序创建该类的其他对象。例如,在连接到数据库的系统中,仅使用一个对象来管理数据库连接。这样可以确保其他对象无法初始化不必要的连接,从而由于多个实例化而使系统的整体性能下降。通过创建多个JDBC连接并观察性能,可以很容易地对其进行测试。性能肯定会受到影响或显着降低。单例模式实质上可以保证系统仅创建一个类的实例。

单例模式

使用单例模式是确保给定类实例化一个且只有一个对象的一种标准技术。这是“四人帮”讨论的二十四个设计模式之一。想法是解决诸如实例化类的单个实例,访问类的唯一实例或控制类实例化过程的问题。实现此目的的关键技术是通过使用私有修饰符隐藏构造函数,并提供一种应用检查和验证的方法,以确保仅创建该类的一个实例。

这很简单,但有效地满足了需求。实际上,通过应用相同的原理,我们可以控制创建类的实例的确切数目,而不仅限于单个实例。但是,这里我们仅关注单个实例。

使用单例模式

不难发现实际上我们只需要一个类的一个实例在内存中的情况。多个对象可能会破坏原因或对正在运行的应用程序的性能造成破坏。在面向对象的编程中,正在运行的应用程序通常在内存中具有许多对象,它们在执行过程中相互作用并扮演着至关重要的角色。但是,在实现线程池,高速缓存,对话框或负责首选项和注册表设置的对象时,数据库连接,日志记录,充当外围设备或图形卡设备驱动程序的对象等都是我们想要的情况。对象运行的单个实例;否则,它将产生很多问题,例如资源阻塞,内存过载以及许多其他不一致的行为。这正是我们需要确定适合于实现单例模式的类并进行相应设计的地方。

实现单例模式

这是该模式的快速实现。

 public final class Singleton {
private static final Singleton singleInstance =
new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return singleInstance;
}
} public class TestSingleton {
public static void main(String[] args){
Singleton s1;
Singleton s2;
s1 = Singleton.getInstance();
s2 = Singleton.getInstance();
if(s1 == s2){
System.out.println("References to same
Singleton object");
}
}
}

Singleton类被声明为final,因此无法创建任何子类。这甚至限制了多重实例化,即使通过对该类进行子类化。构造函数被声明为私有;结果,只有Singleton类可以使用此构造函数创建Singleton对象。对Singleton对象的静态引用将调用私有构造函数,并仅提供该类的一个实例。调用getInstance() 方法时,仅接收对象的参考副本。

在这里,我们通过创建另一个称为TestSingleton的类来使用一个简单的测试。此类声明两个参考Singleton对象,并调用getInstance()方法。然后,我们比较这两个引用,以确保它们实际上引用的是同一运行时实例,而不是两个不同的对象。

有时,我们需要一个仅在第一个静态方法被调用时才创建实例的实现,而不是在此之前。在前面的示例中,对象是静态创建的;getInstance()方法的作用是简单地返回引用。在这种情况下,我们希望在首次调用时创建对象,称为延迟初始化。另外,我们希望调用是线程安全的;否则,可能导致奇怪的不稳定行为或内存泄漏,从而导致JVM崩溃。这是实现此目的的示例。

 public final class Singleton {
private static volatile Singleton singleInstance =
null;
private Singleton(){
}
public static Singleton getInstance(){
if (singleInstance == null) {
synchronized(Singleton.class) {
if (singleInstance == null) {
singleInstance = new Singleton();
}
}
}
return singleInstance;
}
} public class TestSingleton {
public static void main(String[] args){
Singleton s1;
Singleton s2;
s1 = Singleton.getInstance();
s2 = Singleton.getInstance();
if(s1 == s2){
System.out.println("References to same
Singleton object");
}
}
}

也可以使用Enum实现单例。实际上,在可能的情况下,最好使用Enum代替类来实现单例模式。JVM保证从单例Enum中只能创建一个实例。

 public enum SingletonEnum {
SINGLEINSTANCE;
public void someMethod(){
// ...
}
} public class TestSingleton {
public static void main(String[] args){
SingletonEnum s1;
SingletonEnum s2;
s1 = SingletonEnum.SINGLEINSTANCE;
s2 = SingletonEnum.SINGLEINSTANCE;
if (s1 == s2){
System.out.println("References to same
Singleton object");
}
}
}

结论

与往常一样,用户的自由裁量权是良好设计的关键,因为不当使用单例模式可能会导致其他问题。如果单例执行复杂且重量级的操作,则很难对其进行测试。更好的建议是使用依赖项注入框架来构造单个对象。在诸如在GUI应用程序中创建对话框或很少有并发用户的情况下,单例效果最佳。单例模式虽然有用,但在大型可扩展应用程序中造成性能瓶颈方面臭名昭著。

感谢阅读!欢迎留言。想更深入探讨学习也欢迎私信我。下篇继续~

深入探索Java设计模式(二)之策略模式

深入探索Java设计模式(三)之装饰器模式

深入探索Java设计模式(四)之享元模式

深入探索Java设计模式(五)之构建器模式

深入探索Java设计模式之单例模式的更多相关文章

  1. 深入探索Java设计模式(二)之策略模式

    策略设计模式是Java API库中常见的模式之一.这与另一个设计模式(称为状态设计模式)非常相似.本文是在学习完优锐课JAVA架构VIP课程—[框架源码专题]中<学习源码中的优秀设计模式> ...

  2. 深入探索Java设计模式(三)之装饰器模式

    装饰器模式使你可以在运行时使用类似于对象组成的技术来装饰类.这在我们希望实例化具有新职责的对象而无需对基础类进行任何代码更改的情况下尤其有用.本文是在学习完优锐课JAVA架构VIP课程—[框架源码专题 ...

  3. 深入探索Java设计模式(四)之享元模式

    享元模式适用于需要大量相同类型对象的情况.在此,设计布局可以减少创建多个对象的方式.对象在运行时会消耗资源,因此最好在内存中使用较少的对象.它减少了内存占用并利用了程序的整体性能.本文是在学习完优锐课 ...

  4. 深入探索Java设计模式之构建器模式(五)

    抽丝剥茧 细说架构那些事——[优锐课] 简单的程序不需要大量的设计过程,因为它们只关注有限的解决方案,仅使用几个类.大型程序专注于广泛的设计,该设计比好的设计范例的任何其他属性都更能利用可重用性.宏伟 ...

  5. java 设计模式之单例模式

    -------Success is getting what you want, happiness is wanting what you get. java设计模式之单例模式(Singleton) ...

  6. 折腾Java设计模式之单例模式

    博文原址:折腾Java设计模式之单例模式 单例模式 Ensure a class has only one instance, and provide a global point of access ...

  7. Java设计模式之单例模式(七种写法)

    Java设计模式之单例模式(七种写法) 第一种,懒汉式,lazy初始化,线程不安全,多线程中无法工作: public class Singleton { private static Singleto ...

  8. Java 设计模式之单例模式(一)

    原文地址:Java 设计模式之单例模式(一) 博客地址:http://www.extlight.com 一.背景 没有太多原由,纯粹是记录和总结自己从业以来经历和学习的点点滴滴. 本篇内容为 Java ...

  9. java设计模式1——单例模式

    java设计模式1--单例模式 1.单例模式介绍 1.1.核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点 1.2.常见场景 1.3.单例模式的优点 1.4.常见的五种单例模式实现 ...

随机推荐

  1. python中的__call__方法

    在Python中,函数其实是一个对象: >>> f = abs >>> f.__name__ 'abs' >>> f(-) 由于 f 可以被调用, ...

  2. vue3.0里的生命周期函数

  3. PHP安全之道学习笔记1:PHP项目安全设置

    在全球范围来看,超过了80%的网站是使用php进行搭建的,由于脚本语言和早期版本设计的诸多原因,php项目存在不少安全隐患.从配置选项来看,可以做如下的优化. 1.屏蔽PHP错误输出. 在/etc/p ...

  4. 2019-9-28:渗透测试,基础学习,DNS投毒

    该文章仅供学习,利用方法来自网络文章,仅供参考 DNS劫持 目标机:虚拟机下的win7系统 目标ip:192.168.20.131 目标:使用ettercap进行apr投毒,对win7系统就行,DNS ...

  5. http_web_cache

    HTTP Web Cache 程序资源的访问具有局部性 时间局部性:一个被访问过的资源很有可能在近期被再次访问. 空间局部性:一个被访问过的资源,它的周边资源很有可能被访问到. 如何衡量缓存的有效性? ...

  6. yum运行报错:File "/usr/bin/yum", line 30 except KeyboardInterrupt, e: ^SyntaxError: invalid syntax

    这是由于Python升级导致 备份Python 历史版本 [root@sdw1 autoconf]# ls /usr/bin/python* [root@sdw1 autoconf]# mv /usr ...

  7. 深入SQL Server 日期和时间的内部存储

    在SQL Server的内部存储中,日期和时间不是以字符串的形式存储的,而是使用整数来存储的.使用特定的格式来区分日期部分和时间部分的偏移量,并通过基准日期和基准时间来还原真实的数据. 一,DateT ...

  8. IdentityServer4 保护.net framework webapi

    一.IS4服务器配置 1.新建一个Asp.net  Core MVC程序,模板选择 Empty 2.Nuget添加 IdentityServer4,我这里添加的是2.5.3 3.添加Config文件, ...

  9. 算法整理(php语言完成),持续更行中......

    一下所有实例中,均在同一个方法中,所以算法使用内部函数完成 归并排序 public function test1Action () { $tmp = 0; $al_merge = function($ ...

  10. linux命令之less命令

    一.我查看日志特别喜欢用less命令来查看,下面给大家讲解下使用. less(选项)(参数) 选项如下: -e:文件内容显示完毕后,自动退出: -f:强制显示文件: -g:不加亮显示搜索到的所有关键词 ...