6

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

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 未定义。如果我在非单身课程上做同样的事情,他们工作得很好。谢谢。

4

3 回答 3

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 )

我做了以下更改:

  • 合并单例和_单例
  • 将 _instance 更改为 @_instance 以便将其附加到 Singleton 而不是其原型
  • 在 getInstance 中添加了参数 splat(以防需要参数)
  • 将 getInstance() 指向扩展对象而不是 Singleton

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

于 2012-04-13T18:06:09.520 回答
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) 代码,但添加它应该很简单。主要区别在于我的代码正在创建的实例是@or的实例this。这样做将确保首先调用您的构造函数,然后继续父链。您的代码明确地创建了一个实例,_Singleton因此您的Stinky构造函数永远不会被调用。您最终会注意到的另一个小问题是您的getInstance方法实际上并未返回_instance.

我希望这有帮助,

桑德罗

于 2012-04-13T14:55:35.983 回答
1

我不确定目标是什么,但是您可以通过制作Singleton真正的单例(普通对象)来获得相同的结果:

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

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

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

于 2012-04-15T08:10:45.443 回答