我应该如何将这个块分解成更小的功能单元?

时间:2016-08-09 19:32:44

标签: java oop

我正在编写一个应用程序来帮助我的朋友运行一些数字来平衡游戏。

由于有大量的类和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]);

3 个答案:

答案 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]);