web-dev-qa-db-ja.com

クラスが静的なフィールドとメソッドのみを持つのは悪い習慣ですか?

静的メンバー変数と静的メソッドで構成されるonlyクラスがあります。基本的に、汎用ユーティリティクラスとして機能します。

クラスに静的メンバー変数と静的メソッドのみを含めるのは悪い習慣ですか?

70
Stephen Watkins

いいえ、そうは思いません。実際には特定のインスタンスに依存しないインスタンスメソッドでいっぱいのクラスを持つことは、より悪い習慣です。それらを静的にすることで、ユーザーに使用目的を正確に伝えます。さらに、この方法で不要なインスタンス化を回避できます。

編集:後付けとして、一般的に、「ちょうど」という理由で、または「Javaの方法」だと思われるので、言語機能の使用を避けるのが良いと思います。静的ユーティリティメソッドでいっぱいのクラスを持っていた最初の仕事を思い出し、上級プログラマーの1人は、OO power of Javaすべてのメソッドを「グローバル」にすることで、彼女は6か月後にチームにいませんでした。

88
danben

クラスに内部状態がなく、基本的にリーフクラス(ユーティリティクラスはこのカテゴリに分類される)として知られている限り、つまり、他のクラスからは独立しています。それは結構です。

Mathクラスは代表的な例です。

18
Finglas

合理的ですね。

注:これを行うクラスには、プログラマーが静的クラスのインスタンスを作成しようとしたときにコンパイラーがエラーを生成するように、引数のないプライベートコンストラクターが含まれていることがよくあります。

13
Jason S

静的メソッドはあまり気にしません(テストを除く)。

一般的に、静的メンバーは懸念事項です。たとえば、アプリがクラスター化されている場合はどうなりますか?起動時間はどうですか?どのような初期化が行われていますか?これらの問題などについては、Gilad Brachaによる この記事 をご覧ください。

9
Michael Easter

それは完全に合理的です。実際、C#では、この目的のためにstaticキーワードを使用してクラスを定義できます。

3
Taylor Leese

それに夢中にならないでください。 Java.lang.Mathクラスは数学関数のみに関することに注意してください。たとえば、標準APIにはない一般的な文字列処理関数を含むStringUtilitiesクラスもあります。ただし、たとえば、クラスの名前がUtilitiesである場合、それを分割することをお勧めします。

3
Paul Clapham

Javaが静的インポートを具体的に導入したことにも注意してください:( http://en.wikipedia.org/wiki/Static_import

静的インポートは、Javaプログラミング言語で導入された機能であり、メンバー(フィールドおよびメソッド)は、クラスでJavaフィールドが定義されているクラスを指定するこの機能は、バージョン5.0で言語に導入されました。

この機能は、最初にフィールドを定義したクラスを参照することなく、コードに定数を含めるためのタイプセーフなメカニズムを提供します。また、定数インターフェースを作成する慣行を非推奨にするのに役立ちます。定数のみを定義し、そのインターフェースを実装するクラスを作成するインターフェースは、インターフェースの不適切な使用と見なされます[1]。

このメカニズムを使用して、クラスの個々のメンバーを参照できます。

 import static Java.lang.Math.PI;
 import static Java.lang.Math.pow;

またはクラスのすべての静的メンバー:

 import static Java.lang.Math.*;
2

私はそれが合理的な解決策のように聞こえるという意見に同意しますが(他の人がすでに述べているように)、あなたが考慮したいのはデザインの観点から、なぜあなたは「ユーティリティ」目的のためだけにクラスを持っているのかです。これらの機能はシステム全体で本当に一般的なものなのか、それともアーキテクチャ内の特定のクラスのオブジェクトに本当に関連しているのですか。

あなたがそれについて考えている限り、私はあなたのソリューションに問題はないと思います。

2
JasCav

このリンク http://Java.dzone.com/articles/why-static-bad-and-how-avoid は、ほとんどの回答に反するようです。メンバ変数が含まれていない(つまり、状態がない)場合でも、静的クラスはモックや拡張(サブクラス化)ができないため、悪いアイデアになる可能性があります。

1
Andy

Java SDKには静的メンバーのみが含まれる)の Collections クラス.

それで、あなたは適切な正当化がある限りそこに行きます-それは悪いデザインではありません

1
Mihir Mathuria

ユーティリティメソッドは、静的メソッド(StringUtilsなど)のみを含むクラスに配置されることがよくあります。グローバル定数も独自のクラスに配置されるため、残りのコード(public final static属性。

どちらの使用も非常に一般的であり、インスタンス化されないようにするためのプライベートなデフォルトコンストラクターがあります。クラスfinalを宣言すると、静的メソッドをオーバーライドしようとするミスを防ぐことができます。

static member variablesあなたはグローバル定数を意味していなかったので、それらの変数にアクセスするメソッドを独自のクラスに配置したいかもしれません。 その場合、コードでこれらの変数が何をするかについて詳しく説明してもらえますか?

1
rsp

これは通常、ユーティリティクラスの設計方法であり、何も問題はありません。有名な例には o.a.c.l.StringUtilso.a.c.d.DbUtilso.s.w.b.ServletRequestUtils など.

1
Pascal Thivent

オブジェクト指向設計の厳密な解釈によると、ユーティリティクラスは避けるべきものです。

問題は、厳密な解釈に従えば、多くのことを達成するためにクラスを何らかのソートオブジェクトに強制する必要があることです。

Javaデザイナーはユーティリティクラスを作成します(Java.lang.Mathが思い浮かびます)

オプションは次のとおりです。

double distance = Math.sqrt(x*x + y*y);  //using static utility class

対:

RootCalculator mySquareRooter = new SquareRootCalculator();
mySquareRooter.setValueToRoot(x*x + y*y);
double distance;
try{
   distance = mySquareRooter.getRoot();
}
catch InvalidParameterException ......yadda yadda yadda.      

冗長な方法を避けたとしても、次のようになる可能性があります。

Mathemetician myMathD00d = new Mathemetician()
double distance = myMathD00d.sqrt(...);

この例では、.sqrt()はまだ静的なので、そもそもオブジェクトを作成することのポイントは何でしょうか?

答えは、他のオプションがインスタンス変数をまったくまたはほとんど使用しない人工的な「Worker」クラスを作成することである場合、ユーティリティクラスを作成することです。

1
Chris Cudmore

静的メソッドを含むユーティリティクラスについては心配しません。

ただし、静的メンバーは基本的にグローバルデータであるため、使用しないでください。静的メソッドなどの結果をキャッシュするために使用される場合は許容されますが、隠された依存関係やテストの設定の困難など、あらゆる種類の問題につながる可能性がある「実際の」データとして使用される場合。

0
starblue