【问题标题】:Multiple instances of Singleton class. Possible?Singleton 类的多个实例。可能的?
【发布时间】:2015-01-25 15:29:48
【问题描述】:
我找到了this说明链接,其中说明了
确保一个类有一个实例,并提供一个全局访问点
给它。
我最近出现在一次采访中,令我惊讶的是,too 有人问我 单例类可以有多个实例,我的技术是 Java 和 Objective C。我对这个问题的回答是NO 我认为是正确的,因为 Singleton 变量是全局的,应检查它是否为 null。而且这只是第一次null。
但是出于好奇,我正在确认它。有人可以提供一个确认解释天气我是对还是错。
【问题讨论】:
标签:
design-patterns
language-agnostic
singleton
【解决方案1】:
根据定义(设计模式)的单例一词不允许多个实例,但是是的,您可以调整类以创建多个实例,但根据定义它不会被视为单例
【解决方案2】:
精心设计的单例每个应用程序只能有一个实例。
创建多个实例是应用程序设计中的错误。在某些情况下可能会发生,例如:
- 具有延迟初始化的非线程安全单例:多个线程试图获取一个实例并创建多个实例。懒惰单例的好习惯是init on demand
- 使用 DI 容器管理单例(例如 Spring)和多个上下文时,每个上下文都会创建自己的类实例。
【解决方案3】:
单例类可以有多个实例吗?
回答:没有
这是 java 中 Singleton 类的简单示例。通过调用Singleton.getInstance(),您可以获得这个Singleton 类的实例。这里实例是private static,构造函数是private,所以每个JVM只有一个对象可用。
public class Singleton {
private static Singleton instance = new Singleton ();
private Singleton () {
}
public static Singleton getInstance() {
return instance;
}
}
创建单例的延迟实例化也称为经典单例,它不是线程安全版本
public class Singleton {
private static Singleton instance = null;
private Singleton () {
}
public static Singleton getInstance() {
if(instance==null){
instance=new Singleton();
}
return instance;
}
}
一个线程安全的惰性初始化单例类可以简单的实现如下
public class Singleton {
private Singleton() {}
private static class LazyHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}
【解决方案4】:
我正在为建筑师认证做准备,这个问题出现了。
我相信当您访问源代码时会更好地回答这个问题,我相信它是 Erich Gamma / Richard Helm / Ralph Johnson / John Vlissides 所著的 [设计模式:可重用的面向对象软件的元素] 一书。我做了一个快速的研究,并没有发现这个定义早于图书发行。
虽然在开头(第 127 页)它声明其意图是“确保一个类只有一个实例,并提供对其的全局访问点。”在“后果”部分的项目符号 4 中,它具有变体“允许可变数量的实例。该模式可以很容易地改变您的想法并允许 Singleton 类的多个实例。此外,您可以使用相同的方法来控制实例的数量
应用程序使用。仅授予对 Singleton 访问权限的操作
实例需要更改。”
话虽如此,我相信正式的答案是单例可以有多个实例,尽管我特别不认为这在现实世界中得到应用(顺便说一下,无论是谁在你的采访中提出这个似乎都没有真的有兴趣评估你的有用技能)。
【解决方案5】:
我知道这是一个旧的,但我希望我能帮助别人。
遗憾的是,单例模式有很多定义。示例:
Definition 1 HTDIN:
单例模式是应用程序想要的设计解决方案
在所有可能的情况下,任何类都有一个且只有一个实例
没有任何异常情况。
Definition 2 Wikipedia:
在软件工程中,单例模式是一种软件设计
将类的实例化限制为一个对象的模式。
当需要一个对象来协调动作时,这很有用
整个系统。这个概念有时被推广到系统
当只存在一个对象时,它们的运行效率更高,或
将实例化限制为一定数量的对象。术语
来自单例的数学概念。
第一个更严格,但如果您查看第二个描述,则说明可能存在多个实例。这样您就可以执行pooling 之类的操作。
final class Singleton {
private static int ROUND_ROBIN_COUNTER = Integer.MAX_VALUE;
private static final List<Singleton> INSTANCES = Arrays.asList(new Singleton(), new Singleton(), new Singleton());
private Singleton() {}
public static Singleton getInstance() {
return INSTANCES.get(Math.abs((ROUND_ROBIN_COUNTER++)%INSTANCES.size()));
}
}
根据第一个定义,这不是单例,但第二个允许。我正在阅读OCM Java EE 6 Enterprise Architect Exam Guide,它也符合维基百科的定义。
【解决方案6】:
这是一个很好的理论问题,但定义非常明确地指出“确保一个类只有一个实例”这一模式。您可以构建一个几乎相同的模式,允许您实例化最多,比方说,4 个相同类型的对象。
在这种情况下,模式的定义必须是“确保一个类只有有限数量的实例”。
您可以从不同的角度看待问题。您必须将这 4 个对象保存在数据结构中。作为硬编码的单独成员(instance1、instance2、...)或在列表中。在第二种情况下,列表可以被认为是单例。