0

私はelFinderに似たファイルマネージャーフレームワークに取り組んでいます。現在のコードは正常に機能しますが、見栄えを良くしてチェーンを追加したいと思います(チェーンかデコレータパターンかはわかりません)。

これが私がやりたいことのサンプルです:

function UI() {}

UI.prototype.folders = function(){
    return [];
}

UI.prototype.folders.prototype.getSelectedFolder = function(){
   return {};
}

を呼び出すUI.folders()と、フォルダオブジェクトの配列が返されます。したがって、電話をかけるUI.folders()と、次のようなものが得られます。

[
    Object { name="folder1", selected=false }, 
    Object { name="folder2", selected=false }, 
    Object { name="folder3", selected=true }
]

そして、呼び出すUI.folders().getSelectedFolder()と、からの結果がフィルタリングされUI.folders()、次が返されます。

Object { name="folder3", selected=true }

これは可能ですか?この場合、「連鎖」と言うのは正しいですか、それとも「装飾的なパターン」ですか?
そうでない場合-それを行うための別のより適切な方法はありますか?

どんな助けでも本当にありがたいです!

4

3 に答える 3

2

あなたの質問のコードは適切な実装を反映していませんが、直接の質問に答えるには、はい、これ...

UI.folders().getSelectedFolder()

...メソッドチェーンの例です。


デコレータのパターンが異なります。メソッドのセットがあり、それぞれが常に最初に共通の関数を呼び出す必要がある場合は、最初に共通の関数を呼び出し、次に実際の関数を呼び出す関数を返すデコレータを作成できます...

function foo() {
    console.log('I\'m foo, and I\'m first, and I was given these args:', arguments);
}

function decorateWithFoo(decorated) {
    return function () {
        foo.apply(this, arguments);
        decorated.apply(this, arguments);
    };
}

したがってdecorateWithFoo、常に最初に呼び出す関数を作成するために使用できますfoo...

  // create and decorate bar()
var bar = function(a,b) {
    console.log('I\'m bar, and I was called after "foo", and was given args:', a, b);
};
bar = decorateWithFoo(bar);

bar(123, 456); // this will first call `foo()`, then (the original) `bar()`.

  // create and decorate baz()
var baz = function(a,b) {
    console.log('I\'m baz, and I was called after "foo", and was given args:', a, b);
};
baz = decorateWithFoo(baz);

baz(123, 456); // this will first call `foo()`, then (the original) `baz()`.

一部の言語には、デコレータを作成するための構文が組み込まれています。現在、JavaScript はサポートしていません。


さまざまな方法でデコレータを使用していることに気付いた場合は、最初のデコレータ関数を設定する別の関数を作成できます...

function generateDecorator(decorator) {
    return function (decorated) {
        return function () {
            decorator.apply(this, arguments);
            decorated.apply(this, arguments);
        };
    };
}

したがって、オリジナルdecoreateWithFooはこのように設定できたはずです...

function foo() {
    console.log('I\'m foo, and I\'m first, and I was given these args:', arguments);
}

var decorateWithFoo = generateDecorator(foo);
于 2012-04-15T17:35:41.130 に答える
1

これを適切に機能させるには、folders メソッドを、配列から継承するオブジェクトを返す関数にする必要があります。

UI.prototype.folders = function(){
    // must return an object that inherits from an array
    // that has the additional methods on it you want like getSelectedFolder()
}
于 2012-04-15T17:30:34.110 に答える
0

これを解決するいくつかの異なる方法があります。主な目標は、関数を呼び出すと、プロパティが異なる同じタイプのオブジェクトであるオブジェクト/関数を取得することです。私はプロトタイプの使用法のファンではないので、次のようにします(これはそれを解決する1つの方法です):

var FolderList = function ()
{
    var _folders = [];
    folders.pop({ name: "folder1", selected: false });
    folders.pop({ name: "folder2", selected: true });
    folders.pop({ name: "folder3", selected: false });

    // prevent other programers from changing _folders
    // which would break this, so just use a function
    this.folders = function ()
    {
        return _folders;
    }

    this.selectedFolders = function ()
    {
        var tmpFolders = [];
        for (var folderIndex = 0; 
             folderIndex < this._folders.length; 
             folderIndex++)
        {
            if (this._folders[folderIndex].selected)
            {
                tmpFolders.pop(_folders[folderIndex]);
            }
        }
        _folders = tmpFolders;
        return this;
    }

    this.addFolder = function (folder)
    {
        _folders.pop(folder);
        return this;
    }
};

var folderList = new FolderList();
folderList.selectedFolders()
          .addFolder({ name: "folder1", selected: false })
          .addFolder({ name: "folder3", selected: true })
          .selectedFolders();

// array of 2 objects, folder2 and folder3
var arrayOfSelectedFolder = folderList.folders();  
于 2012-04-15T18:17:23.430 に答える