0

1 つまたは複数の他の関数を呼び出す関数、および呼び出されるこれらの関数が、1 つの呼び出し関数によってのみ使用される場合、コードはどのように構造化されるべきでしょうか?

たとえば、あなたが持ってfuncB()いて、匿名関数またはネストされた関数でなければならないことによってのみ呼び出される場合、またはそれらがクラスの一部である場合、それらは単にプライベートと宣言するか、内部クラスに配置する必要がありますかfuncC()?funcA()funcB()funcC()

私は現在 JavaScript を使用していますが、C++ や Java などの他の言語を使用しているときに同じ状況に遭遇しました。

ウィキペディアによると、JavaScript にはネストされた関数がありますが、使用されているのを見たことがありませんか?

4

4 に答える 4

1

プロジェクトを開始するときは、安定するまで機能をカプセル化することを避ける傾向があります。

Dancrumb が指摘したように、関数の呼び出しは無料ではないため、後で多少のリファクタリングが必要になる場合があります。しかし、何ヶ月も触れていないコードを見ていると、そのきれいな組織は精神衛生に良いものになります。そして、チームで作業している場合、それは指数関数的により真実です:)

于 2013-02-19T00:48:31.183 に答える
1

funcB()funcC()が概念的に意味をなさない場合funcA()は、公開しないでください。

従来の OOP では、それらを非公開にする必要があると言うでしょう。

ほとんどの場合、funcB()funcC()が属する別の概念があるというのが私の意見です。それらを別のクラスのパブリック メソッドにする必要があります。保持するものはfuncA()すべて、そのクラスのプライベート インスタンスを保持します。

A、B、C について抽象的に話しながら、説得力のある主張をするのは難しいです。しかし、それらが概念的に属していない場合は、概念的に属してfuncA()いる何か他のものがあると思います。その前提に同意し、構成が継承よりも優れていることに同意する場合、結論はそれらを他のクラスで公開することです。

于 2013-02-19T00:11:57.890 に答える
0

ここにはいくつかのアプローチがあります。

Javascriptは、コード内の任意の場所で定義して変数に割り当てることができる無名関数をサポートしています。

したがって、次のように書くことができます。

function foo() {
  var bar = function() { /* some code */ };

  bar();
}

そして、bar他のどこでも利用できないでしょう。これは機能をカプセル化するのに役立つかもしれませんが、開発のための非常にスケーラブルなモデルではないと思います。

一度だけ呼び出される関数は、将来、複数回呼び出す価値のあるものになる可能性があることを示唆する考え方があります。この場合、「プライベート」な関数を作成できます。

var Foo = (function() {

  var Foo = function() {
    /* some constructor code */
  };

  var private = function() { /* a private function */ };

  Foo.prototype.public = function() {
    private();
    /* And some other stuff */
  };

  return Foo;

})();

var foo = new Foo();
foo.public(); /* Includes a call to the private method */

この場合、あなたのprivate方法は本当にプライベートなので、内部の仕組みを世界に公開する必要はありません。

しかし実際には、それはアクセス変更を実装する方法についての議論です。その質問に答えるためにそこにたくさんの情報があります。より大きな設計上の問題は、個別の機能を実装するのか、それとも単にそれらをインライン化するのかということです。

私の選択は、一般的に、まとまりのある関数を関数に押し込むことです。関数呼び出しのコストはゼロではありませんが、事後に心配してください...関数呼び出しがパフォーマンスのボトルネックであることがわかった場合は、呼び出しが多すぎるかどうか、リファクタリングする必要があるかどうかを心配できます。使用する呼び出しを減らすためのコード。

それまでは、関数を記述して呼び出し、明確なコードを楽しんでください。適切なメソッド名を使用していることを確認してください:)

于 2013-02-19T00:19:43.953 に答える
0

funcB と funcC がクラス内のクロージャーとして作成され、これらをインターフェイスに「公開」しない場合、それらはどのように変更されるかを気にすることなく (削除、追加、異なる値を返すなど...) 変更できます。クラスの外で実装されています。

それらが公開されると、すべての賭けはオフになり、単体テスト、サポートなどが必要になる場合があります。これはよく知られているルールです。

クロージャーは、使用されるスコープ内で宣言された単純な関数です。

方法 A

function MyClass(){

    function funcA(i){
        funcB(i);
        funcC(i);
    }
    function funcB(i){
        //...
    }
    function funcC(i){
        //...
    }
    return {funcA:funcA}
}
va mc = new MyClass()
for(var i = 0;i<100000;i++){    
    mc.funcA(i);
}

方法 B:

function MyClass(){
    function funcA(){
        function funcB(){
        }
        function funcC(){
        }
        for(var i = 0;i<100000;i++){
            funcB();
            funcC();
        }
        // funcB, funcC are created before and then released after this
    }
    return {funcA:funcA}
}
va mc = new MyClass()
mc.funcA();

funcA が何度も呼び出される場合、代入は最適なコストがかかるため、メソッド B はあまり優先されない可能性があります。

メモリを考慮する場合は、方法 B が推奨される場合があります。funcA と funcB は MyClass と MyClass.funcA の両方に常駐しているため、議論の余地がありますが。

于 2013-02-19T01:03:04.337 に答える