2012-04-13 11 views
6

He creado una clase singleton que quiero extender. Funciona (la mitad) porque solo crea una sola instancia de la clase, pero las propiedades agregadas a la subclase no están definidas. Aquí está el singleton originales:Cómo crear coffeescript singleton subclase

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 

Y aquí está la subclase:

Singleton = require('./singleton') 

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


module.exports = Stinky 

Ahora si uso el siguiente en mi aplicación nodo:

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

el método getInstance() se comporta como se esperaba, pero var1 no está definido. Si hago lo mismo en clases que no son singleton, funcionan bien. Gracias.

+1

¿'var1: 'var1'' a typo? ¿Debería ser 'var1 = 'var1'' o en realidad' @ var1 =' var1''? – Sandro

Respuesta

2

Veo cómo está utilizando la clase _Singleton para tratar de simular una clase privada, pero desafortunadamente no creo que pueda usarla en este caso.

Aquí hay un código que funciona:

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​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ 

Quité el Node.js (requiere) código, pero agregó que en debería ser sencillo. La principal diferencia es que la instancia que crea mi código es una instancia de @ o this. Al hacerlo, se asegurará de que su constructor sea llamado primero y luego continúe en la cadena principal. Su código estaba creando explícitamente una instancia de _Singleton por lo que su constructor Stinky nunca fue llamado. Otro problema menor que eventualmente habrías notado fue que tu método getInstance en realidad no estaba devolviendo una instancia de _instance.

espero que esto ayude,

Sandro

+0

Gracias Sandro. Le dará un golpe. –

12

I recortado su código un poco. Estos son los 2 restantes clases:

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) 

me hicieron los siguientes cambios:

  • fusionada Singleton y _Singleton
  • _instance Se cambió a @_instance de modo que se adjunta a Singleton en lugar de su prototipo
  • Argumentos agregados splat en getInstance (en caso de que se necesiten argumentos)
  • Señalando getInstance() al objeto extendido en lugar de Singleton

En este ejemplo, utilicé 2 números diferentes para garantizar que nunca se llamó al 2º constructor.

1

no estoy seguro de cuál es la meta, pero se puede lograr el mismo resultado haciendo Singleton un producto único real (un objeto natural):

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

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

No tiene mucho sentido para Singleton a tener un método que se devuelve a sí mismo.

+0

Esta es la respuesta correcta para el verdadero estilo de Coffeescript (y Javascript). Javascript es un lenguaje basado en prototipos, por lo que los patrones de diseño OOP comunes como Singleton no tienen sentido. – Vortico

+0

@Vortico No estoy de acuerdo. El hecho de que CoffeeScript tenga una palabra clave 'clase' le indica que pretende emular un modelo de herencia basado en clases más familiar. El Cookbook CoffeeScript mantenido por la comunidad incluso tiene una [página en un patrón Singleton] (http://coffeescriptcookbook.com/chapters/design_patterns/singleton). Lamentablemente, la página no menciona la herencia. :( –

Cuestiones relacionadas