在Java中,我们有私有构造函数
public class Singleton{
private static volatile Singleton INSTANCE = null;
private Singleton(){ }
public static Singleton getInstance(){
if(INSTANCE == null){
synchronized(Singleton.class){
if(INSTANCE == null){
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}
这使得一个类无法在类外实例化。在TypeScript中有类似的东西吗?
答案 0 :(得分:2)
这样的事情应该有效:
class Singleton {
private static _instance:Singleton = new Singleton();
constructor() {
if (Singleton._instance){
throw new Error("Error: use getInstance()");
}
Singleton._instance = this;
}
public static getInstance():Singleton {
return Singleton._instance;
}
...
}
同样在java中没有必要使用延迟初始化,因为如果不使用单例,则不会初始化。更好的方法:
public class Singleton {
private static Singleton INSTANCE = new Singleton();
private Singleton() {}
public Singleton getInstance(){
return INSTANCE;
}
}
要回答Zhipeng的评论,静态初始化是线程安全的,如12.4.2中的JLS中所定义:
使用以下过程实现 Java虚拟机负责处理同步和递归初始化 ...
注意:只有在不使用getInstance()的情况下可以使用某些静态方法时,使用延迟实现才有用。在这种情况下,如果从未使用过Singleton类也会被实例化。
有关java上Singleton的完整描述,您可以查看我为Dzone撰写的文章
答案 1 :(得分:2)
我将从java部分开始,并将在@DavideLorenzoMARINO编写的内容上添加一个额外的内容,并且volatile
keyword:
class MySingleton {
private static volatile MySingleton instance;
private MySingleton() {
// do what ever
}
public static MySingleton getInstance() {
if (MySingleton.instance == null) {
MySingleton.instance = new MySingleton();
}
return MySingleton.instance;
}
}
如果你真的想确保它在多线程环境中有效,那么你甚至可能想要考虑" Double Checked Locking"的方法:
class MySingleton {
private static volatile MySingleton instance;
private MySingleton() {
// do what ever
}
public static MySingleton getInstance() {
if (MySingleton.instance == null) {
synchronized (MySingleton.class) {
if (MySingleton.instance == null) {
MySingleton.instance = new MySingleton();
}
}
}
return MySingleton.instance;
}
}
至于打字稿部分,我不认为这种模式在打字稿中运行良好,因为在运行时java不同于防止其他开发人员实例化多个实例。
如果您信任使用该代码的开发人员,那么它很好,但如果没有,那么为什么不在模块/命名空间中包围该实例以便隐藏实现?
类似的东西:
namespace MySingleton {
class MySingletonInstance {
echo(value: string): string {
console.log(value);
return value;
}
}
export var instance = new MySingletonInstance();
}
但是既然你只有这个类的一个实例,那么我认为在javascript中根本不使用一个类更有意义,它只是让事情变得更加冗长,你可以简单地说: / p>
namespace MySingleton {
export interface MySingletonInstance {
echo(value: string): string;
}
export var instance: MySingletonInstance = {
echo: value => {
console.log(value);
return value;
}
}
}
答案 2 :(得分:0)
看看this issue有关如何实现这一目标的一些想法,但请注意TypeScript 2.0将拥有私有构造函数,并且很快就会推出。目前,我建议编写以下代码......
class Singleton {
private static instance: Singleton = new Singleton();
// todo: mark as private when TS 2.0 comes out
constructor() {
}
static getInstance() {
return this.instance;
}
}
...然后在TypeScript 2.0发布后将其更改为私有。