2012-02-01 3 views
11
.

. У меня есть вопрос о лучших практиках с шаблоном проектирования модулей. Приведенный ниже код является примером того, как написаны некоторые из наших Компонентов (мы используем ExtJs, но это не должно иметь большого значения). Мы строим много наших компонентов, как это, и я знаю, что это точно не соответствует лучшим практикам. Есть какие-то мысли, чтобы очистить код?ExtJS (JavaScript). Дизайн модулей. Рекомендации по шаблонам.

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; 

}; 

мне интересно, кое-что об этом и хотел спросить и получить разговор:

  1. Насколько важно, чтобы инициализировать переменные, когда они объявлены (т.е. в верхней части Foo)
  2. Как я мог бы повторно инициализировать часть этого объекта, если клиент этого модуля попадает в состояние, что это foo объект должен быть установлен обратно на это оригиналы
  3. Какие проблемы с памятью может эта конструкция приводит к и как можно реорганизовать этот риск?
  4. Где я могу узнать больше? Существуют ли какие-либо статьи, которые касаются этого, не слишком полагаясь на последний и самый большой из EcmaScript 5?

Обновление 2012-05-24 Я просто хотел бы добавить, я думаю, этот вопрос (Extjs: extend class via constructor or initComponent?) довольно отношения к разговору, особенно с учетом того, что верхние голосовал ответ от «бывшего Ext JS соучредитель и основной разработчик»

Обновление 2012-05-31 еще одно дополнение, этот вопрос также должен быть связан (Private members when extending a class using ExtJS). Кроме того, здесь моя любимая реализация на сегодняшний день:

/*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

[ExtJS Документа-] (http://docs.sencha.com/ext-js/4-0/# !/guide) полны замечательных советов, касающихся этой области. Посмотрите на руководства «Система классов», «Компоненты» и «Архитектура приложений MVC», по крайней мере, они вам помогут. – Tommi

ответ

5

Во-первых, это не специально дизайн модуля шаблон, как я знаю, это общий шаблон конструктор. Модификация модуля, которую я знаю, является одноэлементной, но здесь у вас может быть много экземпляров Foo(). Это, как говорится ...

Вопрос: Насколько важно для инициализации переменных, когда они объявлены (т.е. в верхней части Foo)

Декларирование их на вершине имеет важное значение для ясности, но инициализирует их ISN Это так важно, так как вы делаете это в init. Если вы не делали этого, инициализирует их избавит вас от необходимости делать неопределенную проверку перед тестированием переменной позже:

var x; 

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

Q: Как я мог бы повторно инициализировать часть этого объекта, если клиент этого модуля переходит в состояние, в котором объект foo должен быть установлен обратно на его оригиналы

Есть ли что-то не так с созданием общедоступного метода сброса? Он будет иметь доступ к частным переменным.

function Foo() { 
    // ... 

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

    // ... 
} 

Q: Какие проблемы с памятью, возможно, этот проект приведет к и как я могу реорганизовать, чтобы снизить этот риск?

Я не знаю.

В: Где я могу узнать больше?Существуют ли какие-либо статьи, которые касаются этого, не слишком полагаясь на последний и самый большой из EcmaScript 5?

Вот хорошее чтение о модуле Javascript (и других) модель (ы): http://www.addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript

+0

Я 99.99% собираюсь принять ваш ответ :) Я знаю, медленный ответ, но у меня есть некоторые последующие мысли. Кроме того, я хотел бы ссылаться на это для будущей справки для себя: http://stackoverflow.com/q/4119469/320399 – blong

+0

Любые мысли о шаблоне, описанные в этом ответе? http://stackoverflow.com/questions/1721935/better-way-to-call-superclass-method-in-extjs/#answer-4038890 – blong

+1

У меня недостаточно знаний об ExtJS, чтобы говорить с ним полностью, но это выглядит как сплошная реализация шаблона модуля для меня. – mVChr