大きすぎたり、コードを避ける - Javaで大規模な静的型保証された辞書を保持するエレガントな方法
-
21-08-2019 - |
質問
基本的に私は、レガシー#define
ディレクティブを超えるabstactionあるいくつかの辞書を持っていると思います。
Iが含ま6000+フラグparametersome関数として使用され、これらの定義は、エンティティparameter
の一種を意味している定義を、古いヘッダファイルを有している。
C iにおいて持っている。
GetParameter(... , T_CTITLE, ...);
Javaでは、私が呼び出すしたいと思います。
Connector.getParameter(Parameter.CTITLE, ...);
とパラメータは、ライブラリからパラメータを取得するに関連付けられているすべてのロジックをカプセル化します。
パラメータのインスタンスが自動的にヘッダから抽出され、Javaコードに変換しますが、問題は、パラメータクラスが大きくなりすぎていることですしている - つまり、私はエラーをコンパイルcode too large
取得(私は下線みましょう:もっとその6000個のパラメータがあります)。
そして、私はIDE 0使用自動補完を可能にする方法で、この抽象化を行うために興奮されるだろう、と言うのHashMap
にParameterオブジェクトを格納するくらい嫌いのアイデアをワリーでしょう。
EDIT:パラメータのクラスは次のように定義されています:
public Parameter{
/** logic **/
public static final Parameter<T> parameter1 = new Parameter<T>("NAME", "T", 0xAAB);
...
public static final Parameter<T> parameter6000 = new Parameter<T>("FOO", "T", 0xZZZ);
}
解決
明白なハックは大きな継承チェーン、またはより良いパーティションのインターフェイスに(public static final
ノイズは必要ありません)に分割し、それらのすべてを継承する一つのインターフェイスのいずれかになります。
あなたは、作成コードを小さくすることにより、スペースを節約することができます。代わりに:
new Parameter<T>("NAME", "T", 0xAAB)
ミニマリスト的なアプローチは次のようになります:
parameter("NAME T AAB")
の制限の詳細については、セクションを参照してくださいJVM仕様(第2版)の4.10 の。あなたのコンパイルされたコードがどのようなものであるかを確認するには、 javap
<を使用します/> -c
ます。
他のヒント
たぶん私はあなたが正しく何をしたいのか理解していないんだけど、これは私に列挙のための完璧な使用のように見えます。あなたが列挙型にする機能を追加することができますので、彼らは、あなたがやりたいことができるはず限りのJavaのバージョンが十分に最近のものであるとして(1.5以降)。彼らはあまりにもシリアライズ!
そして6000のリストが大きいですが、はい、それは、オートコンプリートで動作します。
列挙型のサイズに制限があるかどうかは知りませんが、あなたは見つけることができます。
例:
public enum Parameter {
NAME("Pending", "T", 0xAAB), FOO("Foo", "T", 0x1FC);
private final String displayValue;
private final char myChar;
private final int someNum;
private Parameter(String display, char c, int num) {
this.displayValue = display;
this.myChar = c;
this.someNum = num;
}
public String getDisplayValue() {
return displayValue;
}
public char getMyChar() {
return myChar;
}
public int getSomeNum() {
return someNum;
}
}
これは、あなたがあなたが望むものの種類を行うことができます。例:
System.out.println("Hi, the value is " + Parameter.NAME.getSomeNum());
彼らは(結局、の#defineができない)、実行時に変更されませんので、、ENUMは法案を収まる必要があります。
純粋なサイズとしては、それはあなたが少しそれらをcatogorizeしようとすると、列挙型グループのカップルに入れてくださいbehooveかもしれません。
これは、自動補完、==、および、そのような操作を行い、あなたのメタデータを関連付ける機能(番号)を与えます。
基本的に、私は複数のインターフェイスアプローチが進むべき道だと思います。ここで私は、そのソリューションを構築する方法をです。私はあなたのパラメータのコンストラクタの第2引数は何を意味するのか分からないので、私はそれを無視してきます。
で... / COM / yourcompany / legacydefines / Parameter.javaます:
package com.yourcompany.legacydefines;
public class Parameter<T> {
private final String name;
private final T val;
private Parameter(String name, T val) {
this.val = val;
this.name = name;
}
public static <T> Parameter<T> newParameter(String name, T val) {
return new Parameter<T>(name, val);
}
// then, standard getters for "name" and "val"
}
で... / COM / yourcompany / legacydefines / Parameters1.javaます:
package com.yourcompany.legacydefines;
import static com.yourcompany.legacydefines.Parameter.newParameter;
interface Parameters1 {
public static Parameter<String> Parameter0001 = newParameter("ABC", "ABCVAL");
// ...
public static Parameter<Integer> Parameter0999 = newParameter("FOO", 0xABCD);
}
で... / COM / yourcompany / legacydefines / Parameters2.javaます:
package com.yourcompany.legacydefines;
import static com.yourcompany.legacydefines.Parameter.newParameter;
interface Parameters2 {
public static Parameter<String> Parameter1001 = newParameter("DEF", "DEFVAL");
// ...
public static Parameter<Integer> Parameter1999 = newParameter("BAR", 0x1002);
}
(など)
で... / COM / yourcompany / legacydefines / Parameters.javaます:
package com.yourcompany.legacydefines;
interface Parameters extends Parameters1, Parameters2, Parameters3, Parameters4,
Parameters5, Parameters6, Parameters7 {}
次に、あなたの他のコードにだけ使用Parameters.Parameter4562
トムホーティンのポストに拡大し、構造をエンコードするためにJSONを使用することを検討します。
いっそ、あなたが生産結局どんなJARファイル内に吸引されることをJavaコードのパラメータは、XMLまたはJSONファイルに入れて(またはプロパティファイル)ではなく、ハードコードよりも。
私はそれが何をしたいと思います。私は「T」のタイプで、ユーザーがの#define値をキャストする必要がないように、ジェネリックを使用したい、と思います:
public class Parameter<T> {
public final static Parameter<String> NAME = new Parameter<String>("hello");
// .. 5998 more declarations
public final static Parameter<Integer> FOO = new Parameter<Integer>(0xff0b);
private T value;
private Parameter(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
パラメータにアクセスするだけで呼び出します:
String value = Parameter.NAME.getValue();
Javaの定数は、ジェネリック型を反映しているので、我々は唯一のコンストラクタに値を渡す必要がある、の#define名と同じです。コード補完が正常に動作します:)