2012-02-01 19 views
11

Tengo una pregunta sobre las mejores prácticas con el Patrón de diseño del módulo. El siguiente código es un ejemplo de la forma en que se escriben algunos de nuestros componentes (utilizamos ExtJs pero eso no debería importar demasiado). Construimos muchos de nuestros componentes de esta manera y sé que esto no coincide exactamente con las mejores prácticas. ¿Alguna idea de limpiar el código?ExtJS (JavaScript) Diseño de módulos Mejores prácticas de patrones

Ext.ns("TEAM.COMPONENT"); 

function Foo() { 

    // Private vars 
    var privateNumber=0, myButton, privateInternalObject; 

    var numberField = new Ext.form.NumberField({ 
     label : 'A NumberField!', 
     listeners : { 
      'change' : function(theTextField, newVal, oldVal) { 
       console.log("You changed: " + oldVal + " to: " + newVal); 
      } 
     } 
    }); 

    // Some private methods 
    function changeNumField(someNumber) { 
     numberField.setValue(someNumber); 
    } 

    // Some public methods 
    this.publicFunctionSetNumToSomething() { 
     changeNumField(privateNumber); 
    } 

    /** 
    * Initializes Foo 
    */ 
    function init() { 
     // Do some init stuff with variables & components 
     myButton = new Ext.Button({ 
      handler : function(button, eventObject) { 
       console.log("Setting " + numberField + " to zero!"); 
       changeNumField(0); 
      }, 
      text : 'Set NumberField to 0' 

     }); 

     privateInternalObject = new SomeObject(); 
     word = "hello world"; 
     privateNumber = 5; 
    } 

    init(); 

    return this; 

}; 

Me pregunto algunas cosas acerca de esto y quería preguntar y obtener conversación:

  1. ¿Cuán importante es para inicializar las variables cuando son declaradas (es decir, en la parte superior de Foo)
  2. ¿Cómo podría yo volver a inicializar parte de este objeto, si un cliente de este módulo se pone a un estado que es foo objeto necesita ser fijado de nuevo a su originales
  3. ¿Qué tipo de problemas de memoria podría este diseño plomo ay ¿Cómo puedo refactorizar para mitigar ese riesgo?
  4. ¿Dónde puedo obtener más información? ¿Hay algún artículo que aborde esto sin depender demasiado en lo último y lo mejor de EcmaScript 5?

actualización 2012-05-24 Yo sólo quería añadir, creo que esta pregunta (Extjs: extend class via constructor or initComponent?) es bastante relevante para la conversación, sobre todo teniendo en cuenta que la parte superior votó respuesta es de un "ex Ext JS co-fundador y desarrollador del núcleo"

actualización 2012-05-31 Uno más Además, esta cuestión también debe vincularse (Private members when extending a class using ExtJS). Además, aquí es mi aplicación favorita hasta la fecha:

/*jshint smarttabs: true */ 
/*global MY, Ext, jQuery */ 
Ext.ns("MY.NAMESPACE"); 

MY.NAMESPACE.Widget = (function($) { 
    /** 
    * NetBeans (and other IDE's) may complain that the following line has 
    * no effect, this form is a useless string literal statement, so it 
    * will be ignored by browsers with implementations lower than EcmaScript 5. 
    * Newer browsers, will help developers to debug bad code. 
    */ 
    "use strict"; 

    // Reference to the super "class" (defined later) 
    var $superclass = null; 

    // Reference to this "class", i.e. "MY.NAMESPACE.Widget" 
    var $this = null; 

    // Internal reference to THIS object, which might be useful to private methods 
    var $instance = null; 

    // Private member variables 
    var someCounter, someOtherObject = { 
     foo: "bar", 
     foo2: 11 
    }; 

    /////////////////////// 
    /* Private Functions */ 
    /////////////////////// 
    function somePrivateFunction(newNumber) { 
     someCounter = newNumber; 
    } 

    function getDefaultConfig() { 
     var defaultConfiguration = { 
      collapsible: true, 
      id: 'my-namespace-widget-id', 
      title: "My widget's title" 
     }; 
     return defaultConfiguration; 
    } 

    ////////////////////// 
    /* Public Functions */ 
    ////////////////////// 
    $this = Ext.extend(Ext.Panel, { 
     /** 
     * This is overriding a super class' function 
     */ 
     constructor: function(config) { 
      $instance = this; 
      config = $.extend(getDefaultConfig(), config || {}); 

      // Call the super clas' constructor 
      $superclass.constructor.call(this, config); 
     }, 
     somePublicFunctionExposingPrivateState: function(clientsNewNumber) { 
      clientsNewNumber = clientsNewNumber + 11; 
      somePrivateFunction(clientsNewNumber); 
     }, 
     /** 
     * This is overriding a super class' function 
     */ 
     collapse: function() { 
      // Do something fancy 
      // ... 
      // Last but not least 
      $superclass.collapse.call(this); 
     } 
    }); 

    $superclass = $this.superclass; 
    return $this; 

})(jQuery);​ 
+2

[guías de documentación ExtJS] (http://docs.sencha.com/ext-js/4-0/# !/guía) están llenos de excelentes consejos que cubren esta área exactamente. Eche un vistazo a las guías "The Class System", "Components" y "MVC Application Architecture", al menos, le ayudarán mucho. – Tommi

Respuesta

5

En primer lugar, esto no es específicamente un patrón de diseño del módulo como la conozco, este es un patrón general constructor. El patrón de módulo que conozco es singleton, pero aquí podría tener muchas instancias de Foo(). Dicho esto ...

Q: ¿Cuán importante es para inicializar las variables cuando son declaradas (es decir, en la parte superior de Foo)

declararlos en la parte superior es importante para una mayor claridad, pero la inicialización de ellos ISN No es tan importante aquí ya que lo estás haciendo en el init. Si no estuviera haciendo esto, la inicialización de ellos le evita tener que hacer una comprobación indefinido antes de probar la variable más adelante:

var x; 

function baz(){ 
    if (typeof(x) === 'undefined') { 
     // init 
    } else { 
     if (x > 0) { blah } else { blah blah } 
    } 
} 

Q: ¿Cómo puede volver a inicializar parte de este objeto, si un cliente de este módulo llega a un estado en el que es necesario volver a establecer el objeto en sus originales

¿Hay algún error al crear un método público de restablecimiento? Tendrá acceso a las variables privadas.

function Foo() { 
    // ... 

    this.reset = function() { 
     privateNumber = 0; 
     // etc 
    }; 

    // ... 
} 

Q: ¿Qué tipo de problemas de memoria podría conducir a este diseño y cómo puedo refactorizar para mitigar ese riesgo?

No lo sé.

P: ¿Dónde puedo obtener más información?¿Hay algún artículo que aborde esto sin depender demasiado en lo último y lo mejor de EcmaScript 5?

He aquí una buena lectura sobre el módulo Javascript (y otros) patrón (s): http://www.addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript

+0

99,99% voy a aceptar tu respuesta :) Lo sé, respuesta lenta, pero tengo algunos pensamientos de seguimiento. Además, quería hacer un enlace a esto para referencia futura para mí: http://stackoverflow.com/q/4119469/320399 – blong

+0

¿Alguna idea sobre el patrón descrito en esta respuesta? http://stackoverflow.com/questions/1721935/better-way-to-call-superclass-method-in-extjs/#answer-4038890 – blong

+1

No tengo suficiente conocimiento sobre ExtJS para hablarle completamente, pero parece una implementación sólida de un patrón de módulo para mí. – mVChr

Cuestiones relacionadas