私は、いくつかの異なる種類の動物がいる動物園の例に取り組んでいます。ユーザーが「虎を追加」などのコマンドを入力すると、動物園に虎が追加されます。
私のコマンドインタープリタークラスには、次のようなコードがあります。
String animalName...
Animal newAnimal;
if (animalName.equals("tiger"))
newAnimal = new Tiger();
else if (animalName.equals("elephant"))
newAnimal = new Elephant();
ここでの問題は、新しい種類の動物がプログラムに追加されると、このコードも変更しなければならないことです。既存のクラスを何も変更せずに、Animal をサブクラス化するだけで新しい動物を追加したいと思います。
ユーザーがコマンドで指定した名前は、動物のクラス名と必ずしも同じではありません (たとえば、「ベンガル トラを追加」は BengalTiger オブジェクトを追加します)。
可能であれば、リフレクションの使用は避けたいと思います。
これは最終的なコードです:
private static String getClassName(String name) {
char ch;
int i;
boolean upper = true;
StringBuilder s = new StringBuilder("animals.");
for (i=0; i<name.length(); i++) {
ch = name.charAt(i);
if (ch!=' ') {
if (upper)
s.append(Character.toUpperCase(ch));
else
s.append(Character.toLowerCase(ch));
upper = false;
} else
upper = true;
}
return s.toString();
}
@Override
public Animal addAnimal(String s) {
try {
Animal animal = (Animal)Class.forName(getClassName(s)).newInstance();
addAnimal(animal);
return animal;
} catch (InstantiationException e) {
throw new IllegalArgumentException("There are no animals called like this");
} catch (IllegalAccessException e) {
throw new IllegalArgumentException("There are no animals called like this");
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("There are no animals called like this");
} catch (ClassCastException e) {
throw new IllegalArgumentException("There are no animals called like this");
}
}