我的Java程序有问题。我的程序有一个接口Bonus
和九个扩展Bonus
的子类。我必须生成一个Bonus
的随机实例,我不能使用原型模式,因为每个奖金的数量都是随机的,所以我每次需要时都要创建奖金。
切换语句,如果不是解决方案,因为我有太多的子类,代码将非常冗长和粗糙。
所以我决定使用反射,它对我来说非常好,但我的教授告诉我,反射是一个坏技巧,因为不是类型安全的,每次我更改奖金子类的名称,我必须改变我班GenerateBonus
中的代码。
我在互联网上搜索,但没有找到适合我的解决方案。 所以任何人都知道反射的替代方法来生成随机子类的对象吗?
答案 0 :(得分:3)
你需要两件事:
对于创作,如果你不能使用原型,我会使用Supplier
或工厂。以下是供应商的示例:
ArrayList<Supplier<Bonus>> bonuses = new ArrayList<>();
bonuses.add(Bonus1::new);
// ...
bonuses.add(Bonus9::new);
int randomNumber = generateRandomNumber(bonuses.size());
Bonus randomBonus = bonuses.get(randomNumber).get();
对于第一个问题,即获取所有可能奖励的列表,您可以简单地将它们添加到集合中,如上例所示,创建包含所有值的枚举等。
这是一个枚举示例:
enum AllBonuses{
Bonus1(BonusClass1::new),
// ...
Bonus9(BonusClass9::new);
private final Supplier<Bonus> bonus;
AllBonuses(Supplier<Bonus> bonus) { this.bonus = bonus; }
public Bonus create() { return bonus.get(); }
}
// Usage:
int randomNumber = generateRandomNumber(AllBonuses.values().length);
Bonus randomBonus = AllBonuses.values()[randomNumber].create();
我不会使用反射。除非没有别的办法,否则反思很少是一个好的解决方案。
更新:如果您出于某种原因无法使用供应商(例如,您没有Java 8),您可以使用旧的工厂模式:
class Bonus1Factory implements BonusFactory {
@Override
public Bonus create() { return new BonusClass1(); }
}
// ...
ArrayList<BonusFactory> bonuses = new ArrayList<>();
bonuses.add(new Bonus1Factory());
// ...
答案 1 :(得分:1)
使用9个子类我会使用切换语句
int randomSubClass = getRandomNumber();
switch(randomSubClass) {
case 1:
return generateRandomFunBonus();
case 2:
return generateRandomHardBonus();
...
default:
throw new Exception(":(");
}
作为打开int
的替代方法,您可以拥有enum
,每个子类有一个条目和覆盖的create方法。