2

2 つの異なるクラス オブジェクトを返す DBObject という名前のクラスがあります。入力文字列が水である場合は、object1 以外の場合は object2 を返します。

私の要件は、現在、if else に基づいてオブジェクトを返すことです...しかし、将来的にはさらにいくつかのオブジェクトが追加される予定です。それで、コードを静的にするelseifを使用する代わりに、クラスオブジェクトを返す動的な方法はありますか?

つまり、このシナリオで任意の Java デザイン パターンを使用できますか?

コード:

if(str=="water")
 return new object1()
else if...
     return new object3()
else if...
     return new object4()
else if...
     return new object5()
else if...
     return new object6()  
else
  return new object2()
4

4 に答える 4

4

まず、に置き換えif(str=="water")ますif("water".equals(str))。演算子==は参照を比較し、メソッドはequals()オブジェクトを比較します。

第二に、いくつかのアプローチがあります。最初のものは動的クラスローディングを使用しています: Class.forName(className). あなたの場合、シンボリック名と完全修飾クラス名の間のマップを保持できるため、コードは次のようになります。

Class.forName(map.get(str)).newInstance()

具象クラス リストがそれほど動的でない場合はenum、ファクトリとして使用できます。

enum Factory {
    red {
        public Color create() {
            new Red();
        }
    },
    green {
        public Color create() {
            new Green();
        }
    };

    public abstract Color create();
}

String colorName = ...;
Color c = Factory.valueOf(colorName).create();

今後は、たとえば SPI を使用して、利用可能な実装の動的検出を使用できます。

于 2012-09-06T10:46:55.347 に答える
2

ここでは、設計レベルではなく、実装レベルについて話しています。実装には、次のように使用できるJavaReflectionが必要です。

Object obj = Class.forName(type).newInstance();

設計レベルでは、 AbstractFactoryが最も近いパターンです。

于 2012-09-06T10:42:52.243 に答える
2

文字列をキーとして、java.lang.Classを値として使用して、マップを使用できます。クラスはおそらく共通のスーパークラスまたはインターフェイスを共有します。これは、マップ定義でジェネリック型引数として指定できます。

Map<String, Class<? extends SomeSuperClass>> types = new HashMap<String, Class<? extends SomeSuperClass>>();
types.put("water", object1.class);

リフレクションを使用して、クラスのインスタンスを作成できます(詳細については、http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.htmlを参照してください)。

SomeSuperClass instance = types.get("water").newInstance();
于 2012-09-06T10:43:42.073 に答える
0

その文字列を列挙型に置き換えます。これは明らかに、特別な意味を持つ限られた数の値を持つものであり、それぞれのインスタンスが1つだけ必要であり、列挙型にぴったりです。さらに、型安全性が向上します。"fire"それが構築するのに有効なものでない場合、誰かが引数として渡すことはできません。

あなたがそれをするなら:

public enum ObjectType {
    WATER,
    AIR,
    EARTH
}

public static Foo createObject(ObjectType objType) {
    switch (objType) {
        case WATER: return new object1();
        case AIR:   return new object2();
        case EARTH: return new object3();
        default: // throw new IllegalArgumentException or something similar
    }
}

これはかなり理解しやすく、インターフェースが進むにつれてかなり安定していると思います。

オブジェクトの作成がより複雑なnew object1()場合は、ケースでロジックを明示的にコーディングするのではなく、ある種のファクトリオブジェクトのマップを維持することをお勧めします(列挙型はキーオフされています)。createObjectその場合、メソッドのロジックは基本的に。になりますfactoryMap.get(objType).constructInstance()

于 2012-09-06T10:44:05.357 に答える