I've created a singleton class which I want to extend. It (half) works in that it only creates a single instance of the class, but properties added to the subclass are undefined. Here is the original singleton:
class Singleton
_instance = undefined
@getInstance: ->
if _instance is undefined
console.log 'no instance exists, so create one'
_instance = new _Singleton()
else
console.log 'an instance already exists.'
class _Singleton
constructor: ->
console.log 'new singelton'
module.exports = Singleton
And here is the subclass:
Singleton = require('./singleton')
class Stinky extends Singleton
constructor: ->
var1 : 'var1'
module.exports = Stinky
Now if I use the following in my node app:
Stinky = require './stinky'
thing1 = Stinky.getInstance()
thing2 = Stinky.getInstance()
console.log "Thing var1: #{thing1.var1}"
the getInstance() method behaves as expected, but var1 is undefined. If I do this same thing on non singleton classes they work fine. Thanks.
The only way to override a singleton is to have a singleton that expects to be overridden. The simplest way to do this is to provide Singleton that implements an interface (or is otherwise fully abstract itself) that internally instantiates an injected singleton upon the first use of getInstance() .
ES6 Modules are singletons. Thus all you have to do is define your object in a module.
It is a function that gets invoked whenever we create a new of object of this class. But here is a catch: for a class to be a singleton we need to make sure that it creates only one instance, and that's all. To make sure that this happens, we simply create a global variable called instance .
I think it is considered an anti-pattern because a Singleton class can't be instantiated in a normal way by other object (except by calling such method commonly named "getInstance"). So, it will look like the class is being used directly without instantiating it to create a usable object first.
I trimmed your code down a bit. Here are the 2 remaining classes:
class Singleton
@_instance: null
@getInstance: ->
@_instance or= new @( arguments... )
class Stinky extends Singleton
constructor: ( @num ) ->
thing1 = Stinky.getInstance( 1 )
thing2 = Stinky.getInstance( 2 )
console.log( thing1.num, thing2.num )
I made the following changes:
In this example, I used 2 different numbers to ensure that the 2nd constructor was never called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With