4

私はJavaにかなり慣れていません。私は PHP 出身で、魔法の __get および __set メソッドを使用して、php でレジストリ クラスを作成していました。システムの他の部分が簡単にできるように:

registry.foo = new Foo();

私はゲームエンジンを作成しようとしていることに言及する必要があります。Java atm のレジストリは次のとおりです。

class Registry {

    private static Map<String, Object> box = new HashMap<String, Object>();

    public static Object get(String key) {

        if (Registry.box.get(key) != null) {
            return Registry.box.get(key);
        }else {
            return null;
        }
    }

    public static void set(String key, Object o) {
        Registry.box.put(key, o);
    }

}

次に、システムの他の部分がレジストリにアクセスするには、現在、次のすべてが必要です。

((Object) Registry.get("Object")).doSomething();

これは本当にたくさんのコードです。php では、これは次のように簡単に実行できます。

Registry.foo.doSomething();

これをもう少し簡単にする方法はありますか?パブリックフィールドを作成できると思いますが、レジストリクラス自体には不明な新しいオブジェクトを追加する必要がある可能性があるため、レジストリクラスはこれらのフィールドを暗黙的に作成する必要があります..迷惑です:P

前もって感謝します!

4

3 に答える 3

4

これは2つの問題です。

  1. Javaは静的型言語であり、実行時にオブジェクトを定義するための言語内の柔軟性を提供しません(ライブラリを使用して実行時にクラスを合成できますが、#2を参照してください)。
  2. オブジェクトのグローバルレジストリは、タイプセーフな言語での多くの安全性を打ち負かします。アプリケーション全体がオブジェクトの取得とグローバルへの配置を中心としている場合、Mapより安全で結合の少ない設計が存在する可能性があります。

これはどのように解決できますか?

  1. グローバルマップを必要としないようにアプリケーション構造を再設計します。
  2. Java用の動的言語サブセット(Groovyなど)を使用します。
  3. Dynamicまさにあなたが望むことをするタイプを特徴とするScala2.10(JVM互換)を使用してください。
于 2012-12-15T02:42:57.787 に答える
2

まず第一に、この方法は冗長すぎます。

public static Object get(String key) {
    if (Registry.box.get(key) != null) {
        return Registry.box.get(key);
    }else {
        return null;
    }
}

それはただかもしれません:

public static Object get(String key) {
   return Registry.box.get(key);
}

しかし第二に、これは間違いなく悪いデザインです。グローバルリポジトリ-合理的に聞こえません。文字列キーによるすべてのタイプのオブジェクトのストレージ-それはひどいです。

于 2012-12-15T02:46:36.460 に答える
1

これをもう少し簡単にする方法はありますか?

実用的な方法ではありません。Java は静的に型付けされた言語であり、オブジェクトの構造を事前に知っておく必要があります。PHP に相当するというまさにその考えは、言語__get__setは正反対です。

とにかく、あなたの「レジストリ」は悪いデザインのように見えます。(確かに、あなたが示した小さなコードからかなりワイルドな仮定をしています。)無関係なオブジェクトのように見えるもののグローバルリポジトリは必要ありません。代わりに、ある種の依存性注入を検討する必要があります。

次のようにコードを構造化する代わりに、コメントに基づいて:

class World implements GameSystem {

    public void update() {
        Registry.get("game").doSomething();
    }

}

やったほうがいい:

class World implements GameSystem {

    Game game;
    public World(Game game) { // and other dependencies
        this.game = game;
    }

    public void update() {
        this.game.doSomething();
    }

}

プログラムのコンポーネントには、他のコンポーネントを見つける方法を知っているビジネスは実際にはありません。また、コンポーネント間の依存関係が明確になり、循環依存関係を回避するのに役立ちます。

于 2012-12-15T02:39:41.273 に答える