2012-02-01 59 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. 如何重要的是它初始化變量,他們聲明時(在富頂部即)需要
  2. 如何,如果這個模塊的客戶端獲取到的狀態可能我重新初始化該對象的一部分,它的foo對象設置回它的原件
  3. 什麼樣的內存問題可能這樣的設計導致與我該如何重構來緩解那風險?
  4. 我在哪裏可以學到更多?是否有任何文章能夠解決這個問題,而不是過度依賴EcmaScript 5的最新和最大的功能?

2012-05-25 我只是想補充一點,我認爲這個問題(Extjs: extend class via constructor or initComponent?)是談話非常重要,特別是考慮到頂部投票的答案是從「前分機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/# !/指南)完全覆蓋了這方面的重要建議。至少看一下指南「類系統」,「組件」和「MVC應用程序體系結構」,它們將會幫助你很多。 – Tommi 2012-02-02 06:55:30

回答

5

首先,這是沒有具體的模塊設計模式,因爲我知道,這是一個普遍的構造格局。我知道的模塊模式是單例模式,但在這裏可以有許多Foo()的實例。話雖這麼說...

問:如何重要的是他們在聲明時初始化變量(即富的頂部)

頂部聲明他們是爲清楚起見重要,但它們初始化ISN因爲你在初始化時這麼做很重要。如果你不這樣做,他們初始化阻止您有以後的測試變量之前做一個未定義的檢查:

var x; 

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

問:我怎麼可能會重新初始化這個對象的一部分,如果該模塊的客戶端到達的狀態,它是需要被重新設置爲它的原件

有什麼錯建立一個公共的復位方法foo對象?它將有權訪問私有變量。

function Foo() { 
    // ... 

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

    // ... 
} 

問:可能這種設計導致,以及如何能重構我什麼樣的內存問題,以減輕這種風險?

我不知道。

問:我在哪裏可以學到更多?是否有任何文章能夠解決這個問題,而不是過度依賴EcmaScript 5的最新和最大的功能?

下面是關於JavaScript的模塊(及其他)模式(S)很好看的:http://www.addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript

+0

我99.99%會接受你的答案:)我知道,答覆很慢,但我確實有一些後續的想法。此外,我想鏈接到這爲我自己的未來參考:http://stackoverflow.com/q/4119469/320399 – blong 2012-02-17 20:26:02

+0

對此答案中描述的模式的任何想法? http://stackoverflow.com/questions/1721935/better-way-to-call-superclass-method-in-extjs/#answer-4038890 – blong 2012-03-09 13:49:54

+1

我對ExtJS完全沒有足夠的瞭解,但它看起來像一個模塊模式的堅實實現給我。 – mVChr 2012-03-09 17:05:14