Java中的模式和单例
本文针对的是任何第一次遇到设计模式概念的人,他们听说过这个术语单身人士,或者以某种方式实现了单例模式,但不明白发生了什么。CodeGym学生在15级中第一次遇到设计模式,当时船长出乎意料地要求他们通过延迟实现Java Singleton模式来“加强”他们的理解。学生听说单身人士模式第一次立即有很多问题:到底什么是设计模式?我们为什么需要它?什么是单身人士?最后,什么是懒惰的实现?让我们按顺序回答这些问题。
到底什么是设计模式?
我相信一点历史是为了以最好的理解来回答这个问题。有四位著名的编程作家(埃里希·伽马,约翰·弗利赛德斯,拉尔夫·约翰逊和理查德·赫尔姆)提出了一个有趣的想法。他们注意到软件开发通常需要他们解决大致相同的问题,并以相同的方式编写结构的代码。因此,他们决定描述在面向对象编程中经常需要使用的典型模式。他们的书于1994年出版,标题为“设计模式:可重用面向对象软件的元素”。这本书的名字太长了,人们开始简单地称它为四人帮的书。第一版包括23种图案。之后,发现了数十种其他模式。因此,让我们用几句话来总结这一段问题的答案(到底什么是设计模式):
设计模式是常见问题的标准化解决方案。
和单身人士模式只是其中之一。
为什么我们需要设计模式?
你可以在不知道模式的情况下进行编程:毕竟,到15级时,你已经在CodeGym上编写了数百个小程序,甚至不知道它们的存在。这表明设计模式是一种工具,其用法将大师与业余爱好者区分开来:设计模式描述了如何正确解决典型问题。这意味着了解模式可以节省您的时间。通过这种方式,它们类似于算法。例如,您可以使用二十一点和数字创建自己的排序算法,并花费大量时间执行此操作,或者您可以实现一个已经理解和描述很长时间的算法。设计模式也是如此。
此外,使用设计模式,代码变得更加标准,并且在使用适当的模式时,您不太可能犯错误,因为模式的常见陷阱很久以前就被识别并消除了。最重要的是,对模式的了解有助于程序员更好地相互理解。你可以简单地说出一个模式的名称,而不是试图向你的程序员同事提供一个冗长的解释。总而言之,设计模式可以帮助您:
不是重新发明轮子,而是使用标准解决方案
标准化代码
标准化术语
在本节的最后,我们注意到整个设计模式可以分为三大组:
最后,单例模式
单身 人士是一种创造模式。此模式确保一个类只有一个实例,并为此对象提供全局访问点。从描述中可以清楚地看出,此模式应应用于两种情况:
当程序要求不应创建特定类的一个以上对象时。例如,计算机游戏可能有一个 Hero 类,而只有一个 Hero 对象来描述游戏中唯一的英雄。
当您需要提供对对象的全局访问点时。换句话说,您需要使对象从程序中的任何位置都可用。唉,仅仅创建一个全局变量是不够的,因为它没有写保护:任何人都可以更改变量的值,因此对象的全局访问点可能会丢失。a 的这些属性单身 人士是必需的,例如,当您有一个与数据库一起使用的对象,并且您需要从程序的不同部分访问该数据库时。一个单身 人士将确保没有人编写替换以前创建的实例的代码。
所以单身 人士满足了这两个需求:程序中必须只有某种对象中的一个,并且必须全局访问它。在级别 15 的示例中,船长要求您为以下任务实现此模式:
1.查找具有惰性初始化的单例示例。
2.使用相同的原理在单独的文件中创建三个单例类(太阳、月亮、地球)。
3.在太阳、月亮和地球类中实现行星接口。
4.在解决方案类的静态块中调用读取键从控制台和初始化行星方法。
5.实现“从”从“”并初始化“方法方法功能:
5.1. 从控制台读取一个字符串参数
5.2. 如果参数等于行星接口的常量之一,请创建合适的Planet对象。
仔细阅读任务条件后,我们可以清楚地看到为什么单身 人士这里需要。实际上,我们被要求创建以下每个类的实例:太阳、月亮、地球,假设我们只应该创造一个太阳/月亮/地球是有道理的。否则,我们就会陷入荒谬的境地,除非你正在写你的《星球大战》版本。实现单身 人士Java中的模式三个步骤 在Java中,单例行为不能使用普通的构造函数来实现,因为构造函数总是返回一个新对象。因此,的所有实现单身 人士归结为隐藏构造函数,创建控制单例对象生存期的公共静态方法,以及“销毁”所有新出现的对象。如果单身 人士被访问,它应该创建一个新对象(如果程序中尚不存在),或者返回一个现有对象。要完成此操作,请执行以下操作:
1.您需要为该类提供一个存储单个对象的私有静态字段:
2.将(默认)构造函数设为私有。这意味着无法在类外部访问它,并且无法返回新对象:
3.声明一个静态创建方法,该方法将用于获取单例:
上面的例子有点笨拙,因为我们只是隐藏了构造函数,提供了我们自己的方法,而不是一个标准的构造函数。由于本文旨在确保 CodeGym 学生接触到这种模式(以及一般的设计模式),因此这里将不介绍更复杂的单例实现的细微差别。我们只注意到,根据程序的复杂性,此模式可能需要进一步完善。例如,在多线程环境中(请参阅有关线程的文章),多个不同的线程可能会同时访问单例方法,并且上述代码将停止工作,因为每个单独的线程都可以创建类的实例。因此,仍然有几种不同的方法来创建适当的线程安全单例。但那是另一个故事=)
延迟初始化也称为延迟初始化。这是一种编程技巧,其中资源密集型操作(并且创建对象是资源密集型操作)是按需执行的,而不是提前执行的。那么在我们的单身人士Java代码?换句话说,我们的对象是在访问它的时候创建的,而不是提前创建的。你不应该假设懒惰的初始化以某种方式与单身 人士模式。惰性初始化也用于其他创建设计模式,例如代理和工厂方法,但这也是另一个故事=)