現在、実行時に一意のファミリ ID をクラスに割り当てることができるシステムを作成しようとしています。基本的に、実行時にクラスを登録した後、整数値に基づいてクラスを区別できるようにしたいと考えています。
これの使用例は、このシステムがコンポーネント システムの事務処理として使用されることです。すべてのクラスは、クラス Component の子孫 (必ずしも直接である必要はありません) です。実行時に登録されます。
いくつかの理由でこれを実行できるようにしたい:
- 拡張の容易さと安全性: コンポーネントを追加するために、基本コンポーネント システムの巨大なリストを変更する必要はありません。
- 効率: ルックアップは内部でこの整数値を使用して行われるため、検索ルックアップの代わりに O(1) にすることができます。これらのコンポーネントはシステムの大部分を構成するため、インスタンス変数にはしないことを好みます。テストケースでは、> O(1) の削除と挿入を行う余裕がないことがすでに示されているため、この側面を無視することはできません。(最初の実装では、マップ ルックアップ テーブルを使用しました)
コンパイル時にチェックされる実装を探しています。契約ベースのソリューションではありません。Java での契約ベースのソリューションは次のようになります。
interface Component {
// Should return the value of a static variable
int getFamilyID();
int setFamilyID(int id);
}
class Foo implements Component {
static int familyID = 0;
int getFamilyID(){ return familyID; }
int setFamilyID(int id){ familyID = id; }
}
class System { // Singleton
static int registeredComponents = 0;
void register(Component c){ c.setFamilyID(registeredComponents++); }
}
これは明らかに 2 つの理由で機能しません。
- 変数を public にしないと A.getFamilyID() を指定できません。ユースケース: c.getFamilyID() == Foo.getFamilyID(); (インスタンスの代わりに)
- いたるところに冗長なコード。Component の各実装には、コピーして貼り付けた実装が必要です。
C++なら静的変数を指定したテンプレートで解決できると思っていたのですが、コンポーネントの直系の子孫ではないクラスだと使えなくなります。
また、Java 内で列挙型を使用することはできません。列挙型は言語固有であり、コンポーネントの量によって 1 つのファイルのコードが膨大になるためです。(また、それらはすべて1か所で指定する必要があります)
この問題の助けや、私が「間違ったことをしようとしている」(TM)理由についての洞察は、非常に役立ちます:-)
編集:明確にするために、コンポーネントクラスで設定できる静的整数のコード規則をコンパイル時に確実にする方法が必要です。