Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create coffeescript singleton subclass

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.

like image 504
Brad Roodt Avatar asked Apr 13 '12 14:04

Brad Roodt


People also ask

Can we override Singleton class?

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() .

Are ES6 modules singleton?

ES6 Modules are singletons. Thus all you have to do is define your object in a module.

How can use Singleton pattern in Javascript?

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 .

Why singleton is anti pattern in typescript?

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.


1 Answers

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:

  • Merged Singleton and _Singleton
  • Changed _instance to @_instance so that it would be attached to Singleton rather than its prototype
  • Added arguments splat in getInstance (in case arguments are needed)
  • Pointing getInstance() to extended object rather than Singleton

In this example, I used 2 different numbers to ensure that the 2nd constructor was never called.

like image 68
Robert Messerle Avatar answered Sep 28 '22 07:09

Robert Messerle