11

我最近熟悉了揭示模塊模式,並且我閱讀了很多關於它的文章。揭示模塊模式缺點

這似乎是一個很好的模式,我想開始在我有一個大項目中使用它。在我使用的項目中:Jquery,KO,requirejs,Jquery Mobile,JayData。在我看來,它很適合KO ViewModels。我想用THIS這個版本。

我無法找到的一件事是使用這種模式的缺點,是因爲沒有任何(我覺得很難相信)?

開始使用前應該考慮什麼?

+2

選中此文章:http://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript最後有一個缺點部分。 – nemesv

+0

定義模塊模式還克服了模塊模式和顯示模式的一些缺點(如與返回語句的緊密耦合,公共和私有函數如何聲明,私有和公共子例程的非聲明性命名空間以及對象的混合使用字面與返回語句):http://github.com/tfmontague/definitive-module-pattern – tfmontague

回答

4

我讀過@nemesv引用了我的文章(謝謝:)),我認爲還有一個缺點沒有提到,所以我想我會在這裏添加它作爲參考。下面是文章報價:

缺點

這種模式的缺點是,如果一個私有函數是指 公共職能,公共職能不能被覆蓋,如果補丁 是必要。這是因爲私有函數將繼續以 引用私有實現,並且該模式不適用於 公共成員,僅適用於函數。

引用私有變量的公共對象成員也是 受上述無補丁規則註釋的約束。

因此,使用「展示模塊」模式 創建的模塊可能比使用原始模塊 模式創建的模塊更脆弱,因此在使用過程中應該小心。

而且我另外:

不能使用繼承這種模式。例如:

var Obj = function(){ 
    //do some constructor stuff 
} 

var InheritingObj = function(){ 
    //do some constructor stuff 
} 

InheritingObj.prototype = new Obj(); 

InheritingObj.prototype.constructor = InheritingObj; 

這對於JS繼承一個簡單的例子,但使用Revealing Prototype Pattern當你需要這樣做:

InheritingObj.prototype = (function(){ 
    //some prototype stuff here 
}()); 

這將覆蓋你繼承。

+0

它看起來像它與Object.create(urlBuilder)完美的工作;繼承的另一種方法是這樣http://jsfiddle.net/d0n7kfmx/你怎麼看? – user2734550

13

揭示模塊模式(RMP)創建的對象在覆蓋方面表現不佳。結果,使用RMP製造的物體不能很好地用作原型。因此,如果您使用RMP創建要在繼承鏈中使用的對象,則不要這樣做。 這個觀點是我自己的觀點,反對揭示原型模式的支持者。

要看到壞的繼承行爲,採取了網址構建器的下面的例子:

function rmpUrlBuilder(){ 
    var _urlBase = "http://my.default.domain/"; 
    var _build = function(relUrl){ 
    return _urlBase + relUrl; 
    }; 

    return { 
    urlBase: _urlBase, 
    build: _build 
    } 
} 

撇開爲什麼你會使用RMP對於沒有專用部件對象的問題,注意,如果您取回返回的對象,並用「http://stackoverflow.com」覆蓋urlBase,你會期望build()的行爲適當地改變。它並不像看到以下內容:

var builder = new rmpUrlBuilder(); 
builder.urlBase = "http://stackoverflow.com"; 
console.log(builder.build("/questions"); // prints "http://my.default.domain/questions" not "http://stackoverflow.com/questions" 

對比度與下列網址構建器實現

function urlBuilder = function(){ 
    return { 
    urlBase: "http://my.default.domain/". 
    build: function(relUrl){ return this.urlBase + relUrl;} 
    } 
} 

var builder = new urlBuilder(); 
builder.urlBase = "http://stackoverflow.com"; 
console.log(builder.build()); // prints "http://stackoverflow.com/questions" 

其行爲正確的行爲。

您可以使用此範圍作爲修正透露出模塊模式的行爲如下

function rmpUrlBuilder(){ 
    var _urlBase = "http://my.default.domain/"; 
    var _build = function(relUrl){ 
    return this.urlBase + relUrl; 
    }; 

    return { 
    urlBase: _urlBase, 
    build: _build 
    } 
} 

但寧可失敗透露出模塊模式的目的。有關詳細信息,請參見我的博客文章http://ilinkuo.wordpress.com/2013/12/28/defining-return-object-literals-in-javascript/

-2

其他缺點與所述顯示模塊模式包括:

  1. 與Return語句的公共職能緊密耦合
  2. 對象的混合使用字面公共職能和私人功能
  3. 獨立宣言

我推薦使用明確的模塊模式在顯露的模塊模式 (https://github.com/tfmontague/definitive-module-pattern

+0

我不會推薦這種模式,因爲它與揭示模塊模式沒有本質區別。它與被接受的答案中的重寫和原型有相同的缺點。 –

+0

問題是關於「揭示模塊」模式的缺點。這不是關於使用模塊模式的決定。 – tfmontague