I'll start with the java part, and will add one extra thing over what @DavideLorenzoMARINO wrote and that's the 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;
}
}
If you really want to make sure that this works in a multi-threaded environment then you might even want to consider the "Double Checked Locking" approach:
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;
}
}
As for the typescript part, I don't think that this pattern works well in typescript as unlike java at runtime nothing prevents another developer from instantiating more than one instance.
If you trust the developers who work with the code then it's fine, but if not then why not just surround the instance in a module/namespace so that the implementation is hidden?
Something like:
namespace MySingleton {
class MySingletonInstance {
echo(value: string): string {
console.log(value);
return value;
}
}
export var instance = new MySingletonInstance();
}
But since you'll only be having one instance of this class, then I think that in javascript it makes more sense to not use a class at all, it just make things more verbose, and you can simply:
namespace MySingleton {
export interface MySingletonInstance {
echo(value: string): string;
}
export var instance: MySingletonInstance = {
echo: value => {
console.log(value);
return value;
}
}
}