JavaRush /Java 博客 /Random-ZH /模式和单例 - 适合所有第一次遇到它们的人

模式和单例 - 适合所有第一次遇到它们的人

已在 Random-ZH 群组中发布
本文针对的是那些第一次接触模式概念、听说过Singleton'e 或以某种方式制作它,但仍然不理解任何东西的人。欢迎!JavaRush 学生在第 15 级第一次遇到模式,当时上限意外地要求“修复”并使用Singleton惰性实现来实现模式。第一次听说的同学Singleton立马就有一堆疑问:什么是模式,为什么需要它,它是什么样的模式,Singleton最后,这是什么样的惰性实现。我们开始按顺序回答: 模式和单例 - 对于每个第一次遇到它们的人 - 1

到底什么是模式?

为了更好地理解,我认为有必要从历史来回答这个问题。程序员中有这样一位著名的四位作者:Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides,他们提出了一个有趣的想法。
模式和单例 - 对于每个第一次遇到它们的人 - 2
他们注意到,在编写程序时,他们经常必须解决大致相同的问题并编写结构相同类型的代码。因此,他们决定以模式的形式来描述面向对象编程中经常使用的典型模式。该书于 1995 年出版,书名为“面向对象设计技术”。设计模式”。结果书名太长,干脆就叫《四人帮之书》。第一版中发布了 23 种模式,此后又发现了数十种其他模式。因此,在回答本段中的问题“什么是模式?”时,让我们用几句话来总结一下:
模式是常见问题的标准化解决方案。
Singleton只是这些模式之一。

为什么我们需要模式(设计模式)

您可以在不知道模式的情况下进行编程;您可以通过认识到这样一个事实来验证这一点:到 JavaRush 的第 15 级时,您已经编写了数百个小程序,但对它们的存在一无所知。这表明模式是一种工具,它的存在将大师与业余爱好者区分开来:
模式和单例 - 适合所有第一次遇到它们的人 - 3
这些模式描述了如何正确解决典型问题之一。因此,了解这些模式可以节省您的时间。可以用算法来类比。例如,您可以提出自己的二十一点和数字排序算法,并在其上花费大量时间,或者您可以使用很久以前已经描述过的算法并实现它。模式也是如此。另外,通过使用模式,代码变得更加标准化,并且当使用正确的模式时,您将不太可能犯错误,因为在该模式中已经预见并消除了错误。嗯,除此之外,模式知识可以让程序员更好地相互理解。只需说出模板的名称就足够了,而不是试图向其他程序员解释您希望他们做什么。 因此,总而言之,设计模式有助于:
  • 不要重新发明轮子,而是使用标准解决方案;
  • 标准化代码;
  • 术语标准化;
在本节的结论中,我们注意到所有模式都可以简化为三大组:
模式和单例 - 对于每个第一次遇到它们的人 - 4

最后是单例模式

Singleton生成模式。它的直译是孤独的。这种模式确保一个类只有一个对象(该类的一个实例),并且为该对象提供了一个全局访问点。从描述中应该可以清楚地看出,该模式应该在两种情况下使用:
  1. 当您的程序中不应创建任何类的多个对象时。例如,在一款计算机游戏中,您有一个“角色”类,并且该类应该只有一个描述角色本身的对象。

  2. 当您需要为类对象提供全局访问点时。换句话说,您需要确保从程序中的任何位置调用该对象。而且,遗憾的是,为此仅仅创建一个全局变量是不够的,因为它没有写保护,任何人都可以更改该变量的值,并且该对象的全局访问点将丢失。Singleton例如,当您有一个与数据库一起使用的类的对象,并且您需要可以从程序的不同部分访问数据库时,就需要这些属性。并且Singleton它将保证没有其他代码替换了先前创建的类的实例。
解决这两个问题的方法是Singleton:程序中必须只有一个对象,并且必须可以全局访问它。在第 15 级的示例中,上限要求为以下任务实现此模式(以下是其描述):
模式和单例 - 对于每个第一次遇到它们的人 - 5
仔细阅读条件后,就清楚为什么Singleton这里需要 (Single) 了。毕竟,程序要求您为每个类创建一个对象:Sun, Moon, Earth。假设程序中的每个类不应创建超过一个太阳/月亮/地球,这是合乎逻辑的,否则这将是荒谬的,除非您正在编写自己的星球大战版本。 三步Java实现Singleton的特点 Java中的单例行为不能使用常规的构造函数来实现,因为构造函数总是返回一个新对象。因此,Singleton'a 的所有实现都归结为隐藏构造函数并创建一个公共静态方法,该方法将控制单个对象的存在并“销毁”所有新出现的对象。如果Singleton调用 'a,它必须创建一个新对象(如果程序中尚不存在)或返回已创建的对象。为此: #1。– 您需要向包含单个对象的类添加私有静态字段:
public class LazyInitializedSingleton {
	private static LazyInitializedSingleton instance; //#1
}
#2. – 将类构造函数(默认构造函数)设置为私有(以便在类外部关闭对其的访问,然后它将无法返回新对象):
public class LazyInitializedSingleton {
	private static LazyInitializedSingleton instance;
private LazyInitializedSingleton(){} // #2
}
#3 . – 声明一个静态创建方法,用于获取单例:
public class LazyInitializedSingleton {
    private static LazyInitializedSingleton instance;
        private LazyInitializedSingleton(){}
        public static LazyInitializedSingleton getInstance(){ // #3
        if(instance == null){		//if the object has not been created yet
            instance = new LazyInitializedSingleton();	//create a new object
        }
        return instance;		// return the previously created object
    }
}
上面的例子有点笨拙,因为我们只是隐藏了构造函数并提供了我们自己的方法而不是标准构造函数。由于本文旨在让 JavaRush 学生第一次接触这种模式(以及一般模式),因此这里不会给出更复杂的 Singleton 的实现特性。我们仅注意到,根据程序的复杂性,可能需要对此模式进行更详细的细化。例如,在多线程环境中(请参阅线程主题),多个不同的线程可以同时调用 Singleton 的 getter 方法,并且上述代码将停止工作,因为每个单独的线程将能够创建该类的多个实例立刻。因此,仍然有几种不同的方法来创建正确的线程安全单例。但这是另一个故事了 =) 最后。cap 要求的延迟初始化是什么 ? 延迟初始化也称为延迟初始化。这是一种编程技术,其中资源密集型操作(创建对象是资源密集型操作)是按需执行的,而不是提前执行的。这基本上就是我们的代码Singleton'a. 换句话说,我们的对象是在访问时创建的,而不是提前创建的。不应假设延迟初始化的概念在某种程度上与Singleton'om. 延迟初始化也用于其他生成设计模式,例如代理和工厂方法,但那是另一个故事了 =) 在准备本文时使用了以下来源:
  1. Java 单例设计模式最佳实践与示例
  2. 设计模式
  3. Java 中正确的单例
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION