14

私は最近、Revealing Module Pattern (RMP) に精通し、それに関するかなりの数の記事を読みました。

とても良いパターンのようで、大きなプロジェクトで使い始めたいと思っています。私が使用しているプロジェクトでは: Jquery、KO、requireJS、Jquery Mobile、JayData。KO ViewModel に適しているように思えます。

具体的には、このバージョンを使用したいと思います。

私が見つけられなかったのは、このパターンを使用することの欠点です。それは何もないからですか (信じがたいと思います)?

使用を開始する前に考慮すべきことは何ですか?

4

2 に答える 2

16

Revealing Module Pattern (RMP) は、オーバーライドに関して適切に動作しないオブジェクトを作成します。結果として、RMP を使用して作成されたオブジェクトは、プロトタイプとしてうまく機能しません。したがって、RMP を使用して継承チェーンで使用されるオブジェクトを作成している場合は、そうしないでください。この観点は私自身のものであり、Revealing Prototype パターンの支持者とは対照的です。

不適切な継承動作を確認するには、次の URL ビルダーの例を見てください。

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

  return {
    urlBase: _urlBase,
    build: _build
  }
}

なぜプライベート コンポーネントのないオブジェクトに RMP を使用するのかという問題はさておき、返されたオブジェクトを取得して urlBase を " http://stackoverflow.com " でオーバーライドすると、 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"

次の URL ビルダーの実装と動作を比較してください。

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"

これは正しく動作します。

次のようにこのスコープを使用することで、Revealing Module パターンの動作を修正できます。

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/を参照してください。

于 2013-12-31T11:33:44.730 に答える
4

@nemesv さんが参考にしてくださった記事を読んで(ありがとう :))、言及されていない欠点がもう 1 つあると思うので、参考のためにここに追加しておきます。記事からの引用は次のとおりです。

短所

このパターンの欠点は、プライベート関数がパブリック関数を参照する場合、パッチが必要な場合にそのパブリック関数をオーバーライドできないことです。これは、プライベート関数が引き続きプライベート実装を参照し、パターンがパブリック メンバーには適用されず、関数にのみ適用されるためです。

プライベート変数を参照するパブリック オブジェクト メンバーも、上記のノーパッチ ルール ノートの対象となります。

この結果、Revealing Module パターンで作成されたモジュールは、元の Module パターンで作成されたモジュールよりも壊れやすい可能性があるため、使用中は注意が必要です。

そして私の追加:

このパターンでは継承を使用できません。例えば:

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 パターン(ここにアーカイブされています) を使用する場合は、次のようにする必要があります。

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

これは継承をオーバーライドします。

于 2012-12-31T07:14:38.740 に答える