18

定数を保持するためだけにクラスを作成するのは悪い設計だといつも思っていました。しかし最近、私はそれをグーグルで調べてみましたが、定数としてインターフェースを持つことはアンチパターンとしては悪いことだけを発見しました-定数のクラスを使用することについては言及されていません。

定数のクラスは実際にはグローバル変数とそれほど変わらないので、私はそれに反対し、そのようなクラスをリファクタリングする傾向があると私は考えています。コンテキストがまったくないデータのクラスを作成します。これらの定数は、実際に使用するものと結び付けて、コンテキストと意味を与え、クラス内にカプセル化する方がはるかに優れています。

他の人はどう思いますか?

4

7 に答える 7

30

グローバル定数は問題ありません。

グローバル(非定数)変数は悪魔の仕事です。

于 2009-08-12T02:43:11.710 に答える
17

グローバル定数は、それが...である限り、悪い習慣ではありません。

  1. ...不変-グローバル、final/readonly可変オブジェクト(JavaArrayList<T>やC#List<T>など)への参照は定数ではなく、グローバル状態です。
  2. ...>1クラスで必要です。定数が必要なクラスが1つだけの場合は、定数をクラスに直接配置します。(警告:DRYとYAGNIのバランスを適切に取ってください。)

Blochは、Effective Javaの「定数インターフェイス」と「定数クラス」の問題を取り上げ、「定数クラス」アプローチを提唱しています。インターフェイスに定数が必要ない理由は、クライアントクラスがそのインターフェイスを「実装」するように誘導するためです(インターフェイス名をプレフィックスとして付けずに定数にアクセスするため)。ただし、そうすべきではありません。インターフェイスは実際にはオブジェクトの機能へのインターフェイスではなく、クラスの外部型に組み込まれたコンパイル時の利便性です。このことを考慮:

interface C { public static final int OMGHAX = 0x539; }
class A implements C { ... }
class B { private A a; }

クラスBは不必要にに依存するようになりましたCAからの定数を必要としないように変更を実装した場合、外部インターフェイスを壊さずにC削除することはできません-誰か(おそらく非常に愚かな人ですが、そのような人はたくさんいます)は、参照を通じてオブジェクトを参照する可能性があります!implements CAC

定数をクラスに入れ、そのクラスをインスタンス化できないようにすることで、定数クラスが実際にはサブ名前空間として機能することをクライアントに通知します。C#では、クラスをとしてマークしstaticます。Javaでは、クラスを作成しfinalて、到達不能なコンストラクターを指定します。

final class C { 
    private C() { throw new AssertionError("C is uninstantiable"); }
    public static final int OMGHAX = 0x539; 
}

Javaでプログラミングし、定数に定数クラス名を付けずに定数が必要な場合は、このimport static機能を使用できます。

はい、定数を配置するためだけに新しい型を作成することを余儀なくされるのは少し冗長ですが、JavaやC#などの言語では、これを処理する必要があります。定数をどこか配置する必要があります。最良のオプションは、インスタンス化できないクラスです。

于 2009-08-12T11:50:20.073 に答える
10

グローバル変数は、モジュール間でほとんど不要な依存関係を導入するため、問題があります。これらの依存関係により、問題のデバッグとコードの再利用が困難になります。

同じ理由で、真のグローバル定数にも問題があると思います。したがって、MyGlobals.HTTP_SUCCESS_OKのような定数を含むMyGlobalsというシングルトンを使用する代わりに、HttpStatus.SUCCESS_OKなどの独自のクラスに定数のようにパッケージ化します。

于 2009-08-12T03:19:29.357 に答える
7

グローバル変数の問題は、グローバル状態を作成することだと思います。グローバル定数はこれを行いませんが、実際にはコンテキストレス定数の原因であり、これは悪い場合があります。

そのようなものが必要な場合は、列挙型(int定数がある場合)または定数の静的クラスを作成して、コンテキスト(Math.PIなど)を指定できるようにすることをお勧めします。

于 2009-08-12T02:45:01.163 に答える
4

言及されていないことの1つは、より実用的な問題だと思います。コンパイルされた言語を使用している場合は、定数の値を変更するために再コンパイルする必要があることに注意してください。頻繁に変更したい値の場合は、構成ファイルも検討することをお勧めします。

于 2009-08-12T03:31:23.590 に答える
3

場合によっては、グローバル定数は、それらが本当に一定である場合に最適な方法です(プログラムの1つのビルドに対して一定であるだけでなく、おそらくソフトウェア製品の全寿命中およびそれ以降)。

たとえば、それぞれがpi、e、またはHTTP_SUCCESSの独自の定数を宣言する複数のクラスを作成する必要はありません。

一方、グローバル定数は、要件の変更などによって変更される可能性のある任意の値である場合、グローバル変数の問題の多くを引き起こす可能性があります。つまり、これらの定数を構成ファイルに入れることが妥当なオプションのように思われる場合は、グローバル定数であってはなりません。

于 2009-08-12T13:43:17.893 に答える
0

グローバル変数は悪いこととして広く認識されており、一般的には避ける必要があります。これが、非常に多くの人々がシングルトンパターンに問題を抱えている理由です。グローバル変数の問題は、それらが推移的であるということです。

于 2009-08-12T02:45:09.073 に答える