如何创建coffeescript singleton子类

时间:2012-04-13 14:09:31

标签: class node.js singleton coffeescript extend

我创建了一个我想要扩展的单例类。它(一半)的工作原理是它只创建一个类的实例,但是添加到子类的属性是未定义的。这是最初的单身人士:

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

这是子类:

Singleton = require('./singleton')

class Stinky extends Singleton
      constructor: ->
         var1 : 'var1'


module.exports = Stinky

现在,如果我在节点应用中使用以下内容:

Stinky = require './stinky'
thing1 = Stinky.getInstance()
thing2 = Stinky.getInstance()
console.log "Thing var1: #{thing1.var1}"

getInstance()方法按预期运行,但var1未定义。如果我在非单件类上做同样的事情,他们工作正常。感谢。

3 个答案:

答案 0 :(得分:12)

我把你的代码调整了一下。以下是剩余的2个课程:

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 )

我做了以下更改:

  • Merged Singleton和_Singleton
  • 将_instance更改为@_instance,以便将其附加到Singleton而不是其原型
  • 在getInstance中添加了参数splat(如果需要参数)
  • 将getInstance()指向扩展对象而不是Singleton

在这个例子中,我使用了两个不同的数字来确保永远不会调用第二个构造函数。

答案 1 :(得分:2)

我看到你是如何使用_Singleton类来尝试模拟私有类的,但不幸的是我不认为你可以在这种情况下使用它。

以下是一些有效的代码:

class Singleton
   _instance = undefined

   constructor: ->
      console.log 'new singleton'

   @getInstance: ->
      if _instance is undefined
         console.log 'no instance exists, so create one'
         _instance = new @()
      else
         console.log 'an instance already exists.'
      _instance

class Stinky extends Singleton
      constructor: ->
         console.log 'Stinky constructor'
         @var1 = 'var1'


thing1 = Stinky.getInstance()
thing2 = Stinky.getInstance()

console.log "Thing var1: #{thing1.var1}"​​​​​​​​​​​​​​​​​​, thing1, thing2​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

我删除了Node.js(require)代码,但添加该代码应该很简单。主要区别在于我的代码创建的实例是@this的实例。这样做将确保首先调用构造函数,然后继续父链。您的代码显式创建了_Singleton的实例,因此永远不会调用您的Stinky构造函数。您最终会注意到的另一个小问题是,您的getInstance方法实际上并没有返回_instance的实例。

我希望这有帮助,

桑德罗

答案 2 :(得分:1)

我不确定目标是什么,但是你可以通过使Singleton成为一个真正的单例(普通对象)来实现相同的结果:

Singleton =
    doNothing: ->
        # ...
    doMoreNothing: ->
        # ...

class Stinky
    constructor: ->
        @var1: 'var1'
    getInstance: ->
        return Singleton

Singleton有一个返回自身的方法没有多大意义。