2011-02-05 7 views
1

これは基本的なものかもしれませんが、私はこれに関する良いプログラマーの意見を欲しがります。Java変数の宣言

小さなクラスファイルで変数を処理するにはどうすればよいですか?

私は、モジュール化したメソッドと本当に特定のものを行うメソッドを保つのが好きです。 これらのメソッド間で変数を渡してしまいます。多くのメソッドで変数をメンバー変数として使用することをお勧めしますか?あるいは、変数をメソッドに渡す方が良いでしょうか?例えば

:上記の例で

class Test{ 
    somefunction(int a, int b, int c, int d) { 
     doSomething(a, b, c); 
     doOneMoreThing(a, c, d); 
    } 
    void doSomething(int a, int b, int c) { } 
    void doOneMoreThing(int a, int c, int d) { } 
} 

、あなたは変数をメンバ変数として保持する必要があると思いますか? なぜ一方の方法が他方よりも優先される理由を説明してください。

答えて

3

メソッド呼び出しの前後に変数を保持し、値?そうであれば、クラスメンバーでなければなりません。 (少なくともで、一部はクラス - これは必ずしもそうではありません)

それ以外は多少の味です。 1つの重要な要素は、ローカル変数がオブジェクトに状態を追加しないことです。これは、同時に使用すると便利です。すべての変数をローカルに保つことで、クラスを不変にすることさえできます。これにより、通常は自動的にスレッドセーフになります。しかし、シングルスレッド環境であっても、不変クラスは理解しやすく、維持しやすくなります。

OTOHは多くのパラメータを周囲に渡すことが厄介なことがあります。この問題を緩和するには、introducing a Parameter Objectが考えられます。

0

まずはSomefunction(... }は構文エラーです。第2に、メソッド名は小文字で始まり、クラス名は大文字で始める必要があります。第3に、これらのメソッドが何をしているのか、それらのパラメータがどこから来ているのかを知らなくても、最良の方法は何もわからない。

+0

まあ、私は誰も構文エラーを探すとは思わなかった、私はここでコードをデバッグしようとしていなかった。これはほんの一例に過ぎず、私が探しているものを人々がよりよく理解できるようになります。質問/返信を読んだら、関数の詳細を知る必要はありません。 – Maximus

+0

@Maxius:そのため、あなたの問題を示す最小限のコードを投稿する必要があります。また、あなたの質問は主観的なものなので、とにかく答えが得られるだけの十分な情報がありませんでした。 – Falmarri

1

無駄なメンバー変数を持つことは、通常、悪い設計とみなされます。 しかし、多くの方法でその変数を使用すると、複数の変数セットを新しいクラスに組み合わせることができます。

1

オブジェクトの状態を気にしない場合は、メソッドに変数を渡しても問題ありません。私は終わるだろういくつかの変数を持っている場合は

Test.doSomething(1, 2, 3); 
2

:その場合、私は、あなたがクラスをinstansiateする必要はありません、あなたはそうのようなメソッドを呼び出すことができ、この方法でstatic修飾子を使用しますプライベートメソッドの束に渡って、私はしばしば私的な内部労働者クラスにそれらを移動します。代わりに、私は作業者のプロパティに変数は決して違いを移動します

class Foo { 
    public doSomething(...) { 
    // some setup 
    doSomethingRecursively(a, b, c); 
    } 

    private void doSomethingRecursively(A a, B b, C c) { 
    if (baseCase) { ... } 
    doSomethingRecursively(a + 1, b, c); 
    } 
} 

class Foo { 
    public doSomething(...) { 
    // some setup 
    new AppropriatelyNamedHelper(b, c).doSomethingRecursively(a); 
    } 

    private static final class AppropriatelyNamedHelper { 
    final B b; 
    final C c; 

    AppropriatelyNamedHelper(B b, C c) { 
     this.b = b; 
     this.c = c; 
    } 

    void doSomethingRecursively(A a) { 
     if (baseCase) { ... } 
     doSomethingRecursively(a + 1); 
    } 
    } 
} 

これは、各スコープ内の何がそのスコープ内で不変であるかを査読者に明らかにする。

2

クラス内に何らかの種類の状態を維持するためのメンバ変数が存在する必要があります。あなたのクラスが状態を保持している場合、追跡する必要のあるもののメンバ変数を明確に定義します。クラスが状態を維持していない場合、メンバーを作る理由はありません(変数はメンバでなくてはならないレガシーコードをデバッグしなければならず、オブジェクトが複数回呼び出されたときにエラーを引き起こしていました。予測不可能な)。

しかし、「モジュール化」機能が好きかもしれませんが、カップリングと結束について読むことができます。あるクラスに多すぎる機能を持たせることと、より少ない依存性しか持たず、非常に特殊性の高い機能と多くの依存性を持つことのバランスが取れています。

+0

ありがとう、私はこれをよりよく理解するためにカップリング対凝集を読むでしょう! – Maximus

1
  • インスタンス変数:その値はクラスの各インスタンスに固有です。オブジェクトがヒープ内に割り当てられると、各インスタンス変数値のためのスロットがその中にあります。したがって、インスタンス変数は、オブジェクトの作成時に作成され、オブジェクトが破棄されたときに破棄されます。
  • クラス変数:クラス変数は静的なキーワード/修飾子で宣言されています。クラスのインスタンス化の回数に関係なく、クラス変数のコピーは1つだけです。それらは静的メモリに格納されます。
  • ローカル変数:宣言されたメソッド内でのみアクセス可能です。メソッドが入力されると、領域がコールスタックにプッシュされます。この領域には、各ローカル変数およびパラメータのスロットが含まれています。メソッドが呼び出されると、パラメータースロットはパラメーター値に初期化されます。メソッドが終了すると、この領域はスタックからポップされ、メモリは次の呼び出されたメソッドで使用できるようになります。

変数を再利用する場合は、変数をクラス変数として宣言できます。そうでなければ、それぞれのメソッドで定義されたローカル変数でなければなりません。

0

コードを変更する頻度によって異なります(またはデザイン時に変更する頻度について考える必要があります)。署名が変更された場合は、多くの場所で署名を変更する必要があります。つまり、署名をリファクタリングしてもテストするコードが増えます。メンバー変数の作成とカプセル化の面では間違いでしょう。