According to the design rules, a singleton pattern must exist in an instance. If I remove the line of code and return an object, will the function be a single pattern?
const singleton = (function(){
let instance,
counter = 0;
const createInstance = () => ({
getCounter: () => counter,
addCounter: (num) => counter += num,
})
return {
getInsctance: () => createInstance() // insctance || (insctance = createInsctance()) ????
}
})()
const r = singleton.getInsctance()
const r2 = singleton.getInsctance()
r.addCounter(12)
r2.addCounter(32)
singleton.counter = 100
console.log(r2.getCounter()) // 44
console.log(r.getCounter()) // 44
Why is this feature not singleton pattern?
Singleton is a pattern that means that the class/function cannot be a singleton unless there cannot be two instances of it at the same time.
A nice implementation of the singleton pattern can be seen here https://www.dofactory.com/javascript/design-patterns/singleton
var Singleton = (function () {
var instance;
function createInstance() {
var object = new Object("I am the instance");
return object;
}
return {
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
function run() {
var instance1 = Singleton.getInstance();
var instance2 = Singleton.getInstance();
console.log("Same instance? " + (instance1 === instance2));
}
run();
From the outside you cannot call createInstance
, that is, to protect the pattern and you can call getInstance
.
Since the requirement of the singleton pattern is to not have more than one instance, you can have 0 instance and you can destroy an object and create another. But you will need to make sure that at all times there will be no more than one instance of that class/function.
Your code is not following the singleton pattern, because, from the outside it can be instantiated even when it's already instantiated:
const singleton = (function(){
let instance,
counter = 0;
const createInstance = () => ({
getCounter: () => counter,
addCounter: (num) => counter += num,
})
return {
getInsctance: () => createInstance() // insctance || (insctance = createInsctance()) ????
}
})()
const r = singleton.getInsctance()
const r2 = singleton.getInsctance()
alert((r === r2) ? "it is singleton" : "it is not a singleton")
Let's make it a singleton:
const singleton = (function(){
let instance,
counter = 0;
const createInstance = () => ({
getCounter: () => counter,
addCounter: (num) => counter += num,
})
return {
getInsctance: () => instance ? instance : (instance = createInstance()) // insctance || (insctance = createInsctance()) ????
}
})()
const r = singleton.getInsctance()
const r2 = singleton.getInsctance()
alert((r === r2) ? "it is singleton" : "it is not a singleton")
Here I'm reusing the instance instead of creating it if it was already existent.