2011-12-04 15 views
1

私は何かをコード化するときに、関数内のすべてのものを分割しようとします(必要ならば、メソッド)。関数XはものXを行い、Yは凝結Yを行い、ではありません。メソッドXのようなものはX、Y & Z!これにより、より再利用可能なコードが得られます。私はすきです。関数内で関数を呼び出す

var user = { 
    users: [], 
    userCount: 0, 
    addUser: function(user) { 
    (this.users).push(user); 
    }, 
    incrementCount: function() { 
    ++this.userCount; 
    } 
} 

var user = { // 2nd example. 
    users: [], 
    userCount: 0, 
    addUser: function(user) { 
    (this.users).push(user); 
    ++this.userCount; 
    } 
} 

(これはJavaScriptでだが、ここでは言語は非必須である。)

を私の意見では、2番目の例では、より簡単かつ次のようになります:)

は、このコードに見てみましょうをAPIユーザーに使用することができます。 user.incrementCount()に電話するのは忘れやすいです。どう思いますか? 2番目の例は自動的にそれを行います。

どのように天びんを見つけるには?関数内の関数を呼び出すためのベストプラクティスは?

お読みいただきありがとうございます。

編集は:

これが今の私の心に来た:オブジェクトリテラルを使用した場合の機能は本当にプライベートにする方法はありませんので、

var user = { 
    users: [], 
    userCount: 0, 
    addUser: function(user) { 
    (this.users).push(user); 
    this.incrementCount(); 
    }, 
    incrementCount: function() { 
    ++this.userCount; 
    } 
} 

答えて

5

それは、JSで少し違います表記、しかし...

オブジェクトについては、消費者に公開したいものです。 APIのコンシューマは、ユーザーの追加とは別にカウントを増やすことができるようにしますか?その場合:それ以外の場合は

{ addUser: /* snip */, incrementCount: /* snip */ } 

users配列が既にあなたのためのことを行いますので、この特定のケースで

{ addUser: /* snip */, _incrementCount: /* snip */ } 
// or just 
{ addUser: /* snip */ } 

、私は強く、まったく別々のカウントを格納に対して推薦します。

var user = { 
    _users: [], 
    addUser: function(user) { 
     this._users.push(user); 
    }, 
    getUserCount: function() { 
     return this._users.length; 
    } 
    // and if you need to expose the users array directly, 
    , getUsers: function() { 
     return this._users; 
    } 
} 
+0

すべてのAPIと 'user'は単なる例です。 – daGrevis

+0

はい、私はその例に基づいて答えています。 –

1

あなたは「機能A-A」を正しく言っています。 しかし、外部から隠されている(多かれ少なかれ)データに作用する関数は、データに必要なものを(例えばユーザを追加するために)行い、shureを行い、データが正しいことを確認するユーザーのリストがある場合は、Usercounterを増分して常に正確に表示されるようにします)。 APIのユーザーにこのような処理を依頼してもらいたい場合は、とにかく快適ではありません。

ユーザーのリストに機能を追加した場合(たとえば、リストに追加されたことをユーザーに伝え、バイナリツリーにユーザーを格納するなど)、すべてのあなたの機能の外から組織のもの、そこの利点は何ですか?

3

個人的には、APIを介してそのことを公開する必要はありません。また、users.lengthを使用すると、より簡単で(少なくともJavaScriptでは)直感的になります。

最終的には、あなたのインターフェースを本当にシンプルに保つことは、一般的には良いことだと思います。抽象化は良いことです。私が他の誰かの図書館を使用していた場合、私は手動でその価値を増やすことが期待されていることにかなり失望していました。

アップデート:私は思う

もう一つは、言及する価値がある:

あなたのコードは、内部状態を維持し、シンプルなAPIを保つ持つことにより、あなたはまた、ユーザーの生活をより簡単に、しかし、あなただけではなく、誤用を防ぐ(できる限り)。誰かがそのインクリメント方法を間違って使用するシナリオを想像するのは簡単です。その結果、物事が壊れてしまいます。

+0

OPの特定の例に基づいています:私の感情は正確です。 –

1

サンプルコードを単純な例にしようと思っていますが、カウント変数や長さ変数のようなものは、私がこれを独立変数アイテムを追加または削除する関数。オブジェクトを使用するときは、追加するたびにadd()increment()メソッドを呼び出す必要はなく、は、もう一方がなくても、オブジェクトが終わることを望んでいません。無効な状態です。

私はそれを最初のやり方でやっていませんし、確かにあなたがあなたの編集で追加した方法はさらに悪いです。あなたの関数がお互いを呼び出すのに間違っていることは何もありませんが、あなたの例ではインクリメント関数をプライベートにしたいと思います。

カウント変数を非公開にして、関数を介して検索して追加/削除機能を使って設定できるようにする方がよい(ちょうどusers.lengthを返すことができるときにはカウント変数は必要ありません)。すぐに実行される匿名関数を持つ次のパターンでは、private変数と関数を使用できます。また、public関数を含むオブジェクトのみを返します。パブリック関数はまだプライベート変数/関数にアクセスできますが、プライベートなものは外部からアクセスすることはできません。

var user = (function() { 
    var users = [], // private variables 
     private1, 
     private2; 

    function privateFunction1() { /* do something */ } 

    return { 
     getUserCount : function() { 
         return users.length; 
        }, 
     addUser:  function(user) { 
         users.push(user); 
         // return index of new user 
         return users.length - 1; 
        }, 
     getUser :  function(userIndex) { 
         return users[userIndex]; 
        }, 
     someFunc :  function(someParam) { 
         return someParam + privateFunction1(); 
        } 
    } 
})(); 

user.addUser("Fred"); 
user.addUser("Mary"); 
console.log(user.getUserCount()); // 2 
console.log(user.getUser(1));  // Mary 
関連する問題