我正在编写一个应用程序来帮助我的朋友运行一些数字来平衡游戏。
由于有大量的类和stat变量,这已成为比我最初想象的更大的项目。
我正在制作HeroObject
s,它应该代表英雄的统计数据。该对象由每个类(即Marksman
)扩展,该类提供与该类相关的特定功能。我正在通过csv
文件阅读这些英雄,因此可以同时测试多个类和技能公式。这是我用来制作HeroObject
的函数:
private HeroObject makeHero(String[] heroLine) {
switch(heroLine[11].toLowerCase()) {
case "rogue":
return new Rogue(Integer.valueOf(heroLine[0]), Integer.valueOf(heroLine[1]),
Integer.valueOf(heroLine[2]), Integer.valueOf(heroLine[3]),
Integer.valueOf(heroLine[4]), Integer.valueOf(heroLine[5]),
Integer.valueOf(heroLine[6]), Integer.valueOf(heroLine[7]),
Integer.valueOf(heroLine[8]), Integer.valueOf(heroLine[9]),
heroLine[10]);
case "marksman":
return new Marksman(Integer.valueOf(heroLine[0]), Integer.valueOf(heroLine[1]),
Integer.valueOf(heroLine[2]), Integer.valueOf(heroLine[3]),
Integer.valueOf(heroLine[4]), Integer.valueOf(heroLine[5]),
Integer.valueOf(heroLine[6]), Integer.valueOf(heroLine[7]),
Integer.valueOf(heroLine[8]), Integer.valueOf(heroLine[9]),
heroLine[10]);
case "knight":
return new Knight(Integer.valueOf(heroLine[0]), Integer.valueOf(heroLine[1]),
Integer.valueOf(heroLine[2]), Integer.valueOf(heroLine[3]),
Integer.valueOf(heroLine[4]), Integer.valueOf(heroLine[5]),
Integer.valueOf(heroLine[6]), Integer.valueOf(heroLine[7]),
Integer.valueOf(heroLine[8]), Integer.valueOf(heroLine[9]),
heroLine[10]);
case "lancer":
return new Lancer(Integer.valueOf(heroLine[0]), Integer.valueOf(heroLine[1]),
Integer.valueOf(heroLine[2]), Integer.valueOf(heroLine[3]),
Integer.valueOf(heroLine[4]), Integer.valueOf(heroLine[5]),
Integer.valueOf(heroLine[6]), Integer.valueOf(heroLine[7]),
Integer.valueOf(heroLine[8]), Integer.valueOf(heroLine[9]),
heroLine[10]);
case "windadept":
return new WindAdept(Integer.valueOf(heroLine[0]), Integer.valueOf(heroLine[1]),
Integer.valueOf(heroLine[2]), Integer.valueOf(heroLine[3]),
Integer.valueOf(heroLine[4]), Integer.valueOf(heroLine[5]),
Integer.valueOf(heroLine[6]), Integer.valueOf(heroLine[7]),
Integer.valueOf(heroLine[8]), Integer.valueOf(heroLine[9]),
heroLine[10]);
case "wateradept":
return new WaterAdept(Integer.valueOf(heroLine[0]), Integer.valueOf(heroLine[1]),
Integer.valueOf(heroLine[2]), Integer.valueOf(heroLine[3]),
Integer.valueOf(heroLine[4]), Integer.valueOf(heroLine[5]),
Integer.valueOf(heroLine[6]), Integer.valueOf(heroLine[7]),
Integer.valueOf(heroLine[8]), Integer.valueOf(heroLine[9]),
heroLine[10]);
case "lightningadept":
return new LightningAdept(Integer.valueOf(heroLine[0]), Integer.valueOf(heroLine[1]),
Integer.valueOf(heroLine[2]), Integer.valueOf(heroLine[3]),
Integer.valueOf(heroLine[4]), Integer.valueOf(heroLine[5]),
Integer.valueOf(heroLine[6]), Integer.valueOf(heroLine[7]),
Integer.valueOf(heroLine[8]), Integer.valueOf(heroLine[9]),
heroLine[10]);
case "lightadept":
return new LightAdept(Integer.valueOf(heroLine[0]), Integer.valueOf(heroLine[1]),
Integer.valueOf(heroLine[2]), Integer.valueOf(heroLine[3]),
Integer.valueOf(heroLine[4]), Integer.valueOf(heroLine[5]),
Integer.valueOf(heroLine[6]), Integer.valueOf(heroLine[7]),
Integer.valueOf(heroLine[8]), Integer.valueOf(heroLine[9]),
heroLine[10]);
case "iceadept":
return new IceAdept(Integer.valueOf(heroLine[0]), Integer.valueOf(heroLine[1]),
Integer.valueOf(heroLine[2]), Integer.valueOf(heroLine[3]),
Integer.valueOf(heroLine[4]), Integer.valueOf(heroLine[5]),
Integer.valueOf(heroLine[6]), Integer.valueOf(heroLine[7]),
Integer.valueOf(heroLine[8]), Integer.valueOf(heroLine[9]),
heroLine[10]);
case "fireadept":
return new FireAdept(Integer.valueOf(heroLine[0]), Integer.valueOf(heroLine[1]),
Integer.valueOf(heroLine[2]), Integer.valueOf(heroLine[3]),
Integer.valueOf(heroLine[4]), Integer.valueOf(heroLine[5]),
Integer.valueOf(heroLine[6]), Integer.valueOf(heroLine[7]),
Integer.valueOf(heroLine[8]), Integer.valueOf(heroLine[9]),
heroLine[10]);
case "earthadept":
return new EarthAdept(Integer.valueOf(heroLine[0]), Integer.valueOf(heroLine[1]),
Integer.valueOf(heroLine[2]), Integer.valueOf(heroLine[3]),
Integer.valueOf(heroLine[4]), Integer.valueOf(heroLine[5]),
Integer.valueOf(heroLine[6]), Integer.valueOf(heroLine[7]),
Integer.valueOf(heroLine[8]), Integer.valueOf(heroLine[9]),
heroLine[10]);
case "darkadept":
return new DarkAdept(Integer.valueOf(heroLine[0]), Integer.valueOf(heroLine[1]),
Integer.valueOf(heroLine[2]), Integer.valueOf(heroLine[3]),
Integer.valueOf(heroLine[4]), Integer.valueOf(heroLine[5]),
Integer.valueOf(heroLine[6]), Integer.valueOf(heroLine[7]),
Integer.valueOf(heroLine[8]), Integer.valueOf(heroLine[9]),
heroLine[10]);
}
return null;
}
我不必指出这是多少重复代码,但我不确定如何将case部分分解为自己的类而不再检查类是什么。
TL; DR:
每个类都扩展HeroObject
,因此具有相同的构造函数,但我仍然需要通过各自的接口创建它们。如何在功能上分离以下块:
return new SomeClass(Integer.valueOf(heroLine[0]), Integer.valueOf(heroLine[1]),
Integer.valueOf(heroLine[2]), Integer.valueOf(heroLine[3]),
Integer.valueOf(heroLine[4]), Integer.valueOf(heroLine[5]),
Integer.valueOf(heroLine[6]), Integer.valueOf(heroLine[7]),
Integer.valueOf(heroLine[8]), Integer.valueOf(heroLine[9]),
heroLine[10]);
答案 0 :(得分:5)
您当然应该分开阅读Excel文件并从Hero
类创建实例。
我创建了一个HeroFactory
(也称为虚拟构造函数),它可以为我提供Hero
和任何其他子类的实例。
对于每种情况,Excel文件中的列看起来都是相同的。而不是switch语句,传入你想要的对象类型。
public class HeroFactory {
public static final Hero createHero(Class heroClass) {
// create the type of Hero here based on Class passed in. You can use reflection to make it clean. No switch needed.
}
}
使用其他构造函数可以轻松减少代码量:
public class Hero {
public Hero(String [] parameters) {
// initialize your stuff by iterating over the parameters instead of passing 11 values.
}
}
答案 1 :(得分:2)
一方面,你走的是一条好路:你(不知何故)转向工厂模式。当然,正如duffymo所说,这可以延长。
但这不会解决你的真正问题:那就是 - 你正在使用低级抽象!你看,你正在使用一个字符串数组来表示重要信息;因此您的工厂代码非常复杂。
含义:在精心设计的OO设置中,您应该避免在创建时需要超过2,3个参数的对象。换句话说:你真的必须退后一步,想一想如何提高基于你设计的模型的质量。你看,类/接口,它们都存在以提供有用的抽象。你的课程没有这样做;因为从本质上讲,你是在切换字符串;并从字符串构建一切。
根本原因:对于包含META信息的数据,CSV可能是错误的格式?
长话短说:您正在尝试使用包含不充分元信息的数据来处理您的代码。如果这是一个选项,您应该退一步考虑是否可以从CSV更改为JSON。
含义:不要将字符串放入文件中。将对象放入您的文件中;并从那里读回来。
如果所有这一切都不可能;那么我眼中只有两种选择:正如duffymo所暗示的那样;考虑使用反射。但是......做这样“动态”的事情......这不是Java真正擅长的事情。如果你真的需要很多“代码动态”;根据您正在使用的数据 - 也许其他语言可以让您更快地到达目的地。你知道,元编程在python,ruby中更容易做... ...
答案 2 :(得分:0)
尝试制作另一个HeroObject构造函数,但让它包含一个int数组和最后一个值。
public HeroObject (int[] heroValues, Object heroLine )
{
this(heroValues[0], heroValues[1],
heroValues[2], heroValues[3],
heroValues[4], heroValues[5],
heroValues[6], heroValues[7],
heroValues[8], heroValues[9],
heroLine);
}
在切换之前构建int数组。
int[] heroValues = new int[] {
Integer.valueOf(heroLine[0]), Integer.valueOf(heroLine[1]),
Integer.valueOf(heroLine[2]), Integer.valueOf(heroLine[3]),
Integer.valueOf(heroLine[4]), Integer.valueOf(heroLine[5]),
Integer.valueOf(heroLine[6]), Integer.valueOf(heroLine[7]),
Integer.valueOf(heroLine[8]), Integer.valueOf(heroLine[9])};
然后像这样调用构造函数。
new SomeClass(heroValues, heroLine[10]);