実用的なJavaScriptオブジェクト指向のデザインパターンの例


81

アプリケーションのJavaScriptでどのオブジェクト指向のデザインパターンを使用していますか。その理由は何ですか。

正式なデザインパターンが添付されていない場合でも、コードを投稿してください。

私はたくさんのJavaScriptを書いてきましたが、私がしていることに多くのオブジェクト指向パターンを適用しておらず、私は多くを見逃していると確信しています。


あなたが思うかもしれない意味で、あなたはおそらく古典的なOOPを見たことがないでしょう。ただし、おそらく典型的なOOPの機能を利用したことがあり、実際にそれを実現したことはありません。
デイブ2010

私は実際に(時々)OOPを使用していることに気づきます-私はOOPについてもっと慎重になりたいという理由だけで、もっと意識的にOOPを使い始めたいと思っています
ming yeow 2010

他の人がコードで行うことのリストを要求しているだけなので、この質問をトピック外として閉じることに投票します。
アルモ2018

回答:


54

以下は、3つの一般的なJavaScriptパターンです。これらはクロージャのために簡単に実装できます:

また、チェックアウトすることもできます。

以下は、Diazが発表した2008年のGoogle I / Oトークで、彼の本のいくつかのトピックについて説明しています。


いいね!カレーは、私がやろうとしていた一般化のいくつかを行うためのより賢い方法のように見えます。すでに単純な形式のモジュールとメモ化を使用していますが、これらの例を調べて、現在の方法を推し進める必要があります。どれを一番よく使いますか?
ming yeow 2010

@ming:おそらく、それはモジュールパターンです。実装と理解が非常に簡単で、名前空間やプライベート変数/メソッドなど、いくつかの優れた機能が付属しています。
Daniel Vassallo 2010

26

継承

私はExtJS3に基づく継承の表記法を使用しています。これは、Javaで古典的な継承をエミュレートするのに非常に近い動作をします。基本的に次のように実行されます。

// Create an 'Animal' class by extending
// the 'Object' class with our magic method
var Animal = Object.extend(Object, {
    move : function() {alert('moving...');}
});

// Create a 'Dog' class that extends 'Animal'
var Dog = Object.extend(Animal, {
    bark : function() {alert('woof');}
});

// Instantiate Lassie
var lassie = new Dog();

// She can move and bark!
lassie.move();
lassie.bark();

名前空間

また、名前空間に固執することについてEric Miragliaに同意します。そのため、上記のコードはウィンドウオブジェクトの外部の独自のコンテキスト内で実行する必要があります。これは、ブラウザーウィンドウで実行される多くの同時フレームワーク/ライブラリの1つとしてコードを実行する場合に重要です。

これは、ウィンドウオブジェクトへの唯一の方法が、独自の名前空間/モジュールオブジェクトを経由することを意味します。

// Create a namespace / module for your project
window.MyModule = {};

// Commence scope to prevent littering 
// the window object with unwanted variables
(function() {

    var Animal = window.MyModule.Animal = Object.extend(Object, {
         move: function() {alert('moving...');}
    });

    // .. more code

})();

インターフェイス

また、インターフェースなどのより高度なOOP構造を利用して、アプリケーション設計を強化することもできます。これらに対する私のアプローチは、Function.prototypeこれらの線に沿って表記を取得するためにを拡張することです。

var Dog = Object.extend(Animal, {
     bark: function() {
         alert('woof');
     }
     // more methods ..
}).implement(Mammal, Carnivore);

OOパターン

Javaの意味での「パターン」に関しては、シングルトンパターン(キャッシュに最適)と、ユーザーがボタンをクリックしたときにいくつかのアクションを割り当てるなどのイベント駆動型機能のオブザーバーパターンの使用しか見つかりませんでした。

オブザーバーパターンを利用する例は次のとおりです。

// Instantiate object
var lassie = new Animal('Lassie');

// Register listener
lassie.on('eat', function(food) {
   this.food += food;
});

// Feed lassie by triggering listener
$('#feeding-button').click(function() {
    var food = prompt('How many food units should we give lassie?');
    lassie.trigger('eat', [food]);
    alert('Lassie has already eaten ' + lassie.food + ' units');
});

そして、それはOO JSの私のバッグのほんの2、3のトリックです、それらがあなたに役立つことを願っています。

この道を進むつもりなら、Douglas Crockfords Javascript:The GoodPartsを読むことをお勧めします。このようなもののためのその素晴らしい本。


20

私はモジュールパターンのファンです。これは、拡張可能で非依存の(ほとんどの場合)フレームワークを実装する方法です。

例:

フレームワークはQ、次のように定義されています。

var Q = {};

関数を追加するには:

Q.test = function(){};

これらの2行のコードは、モジュールを形成するために一緒に使用されます。モジュールの背後にある考え方は、この場合Q、すべてがいくつかの基本フレームワークを拡張しますが、相互に依存せず(正しく設計されている場合)、任意の順序で含めることができるということです。

モジュールでは、フレームワークオブジェクトが存在しない場合は、最初に作成します(これはシングルトンパターンの例です)。

if (!Q)
    var Q = {};

Q.myFunction = function(){};

そうすれば、複数のモジュール(上記のような)を別々のファイルに入れて、それらを任意の順序で含めることができます。それらのいずれかがフレームワークオブジェクトを作成し、それを拡張します。フレームワークが存在するかどうかを手動で確認する必要はありません。次に、モジュール/関数がカスタムコードに存在するかどうかを確認するには:

if (Q.myFunction)
    Q.myFunction();
else
    // Use a different approach/method

1
これは非常に便利に見えます。これをコードでどのように使用していますか?共有してくれてありがとう!
ming yeow 2010

最近行ったプロジェクトで使用しました。このプロジェクトでは、共通の機能、UI、およびその他の2つの特殊なメカニズム用に個別のJavaScriptファイルがありました。すべてのファイルが同じフレームワーク(上記の方法を使用して定義)に関数を追加し、上記のように関数を呼び出しました。
Chris Laplante 2010

このタイプの手法の主な用途の1つは、グローバル名前空間の汚染を回避することです。何がもっと汚染しますか?単一のQフレームワーク変数、または数十から数十の関数と変数?
Chris Laplante 2010

6

シングルトンパターンは、多くの場合、「カプセル化」や組織化に非常に役立ちます。アクセシビリティを変更することもできます。

var myInstance = {
  method1: function () {
    // ...
  },
  method2: function () {
    // ...
  }
};

javascriptでシングルトンを実装する最もクリーンな方法


素晴らしい-これは私がいつも使っているものです!しかし、それは私のjavascriptOOの範囲とほぼ同じです。;)
ming yeow 2010

4

私はjqueryのメソッドチェーンパターンが本当に好きで、1つのオブジェクトで複数のメソッドを呼び出すことができます。これにより、1行のコードで複数の操作を非常に簡単に実行できます。

例:

$('#nav').click(function() {
   $(this).css('color','#f00').fadeOut();
});

右-同意しました!以前にこれらの方法で機能する独自のカスタムメソッドを開発したことがありますか?
ming yeow 2010

3

jQueryプラグインを使用したデコレータパターンが本当に好きです。ニーズに合わせてプラグインを変更するのではなく、リクエストを転送し、パラメータと機能を追加するカスタムプラグインを作成します。

たとえば、あなたはすべての時間を中心に、デフォルト引数のセットを渡す必要がある、とあなたはビジネスロジックへの絆は、何でもないプラグイン書くことを少し-異なる動作が必要な場合prepost、ニーズに合わせて必要な仕事と自分のデフォルト引数を渡すをそれらの特定の引数が指定されていない場合。

これの主な利点は、ライブラリを更新でき、ライブラリの変更を移植することを心配しないことです。コードが壊れている可能性はありますが、少なくとも壊れない可能性はあります。


これは素晴らしいアイデアのように聞こえます。実際の拡張を行うためのコードの実際の例はありますか?簡単な例でも、誰もが大いに役立ちます。
ming yeow 2010

3

javascriptの世界で役立つパターンの1つは、LINQによって最初に普及し、jQueryでも使用されるチェーンパターンです。

このパターンにより、クラスのさまざまなメソッドを連鎖的に呼び出すことができます。

このパターンの主な構造は次のようになります

var Calaculator = function (init) {
    var result = 0;
    this.add = function (x) { result += (init + x); return this; };
    this.sub = function (x) { result += (init - x); return this; };
    this.mul = function (x) { result += (init * x); return this; };
    this.div = function (x) { result += (init / x); return this; };

    this.equals = function (callback) {
        callback(result);
    }

    return this;
};


new Calaculator(0)
    .add(10)
    .mul(2)
    .sub(5)
    .div(3)
    .equals(function (result) {
        console.log(result);
    });

このパターンの重要なアイデアはthis、電卓機能の他のパブリックメンバーへのアクセスを可能にするキーワードです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.