重构在Java

时间:2017-05-10 19:54:19

标签: java

我必须在这个程序中分配一个随机数量的对象,目前我知道这样做的唯一方法就是这样:

    if (star.returnZones() == 1) {
        this.createPlanet(planet1, star);
    }
    else if (star.returnZones() == 2) {
        this.createPlanet(planet1, star);
        this.createPlanet(planet2, star);
    }
    else if (star.returnZones() == 3) {
        this.createPlanet(planet1, star);
        this.createPlanet(planet2, star);
        this.createPlanet(planet3, star);
    }
    else if (star.returnZones() == 4) {
        this.createPlanet(planet1, star);
        this.createPlanet(planet2, star);
        this.createPlanet(planet3, star);
        this.createPlanet(planet4, star);
    }
    else if (star.returnZones() == 5) {
        this.createPlanet(planet1, star);
        this.createPlanet(planet2, star);
        this.createPlanet(planet3, star);
        this.createPlanet(planet4, star);
        this.createPlanet(planet5, star);
    }

我确信这是一种更有效的方法,每个人都可以做到这一点。我将使用术语asAbovePlus来表示上述所有内容,还有一件事。

if (star.returnZones() == 1) {
    this.createPlanet(planet1, star);
}
else if (star.returnZones() == 2) {
    asAbovePlus
    this.createPlanet(planet2, star);
}

有没有办法在Java中做这样的事情?这真的很有用。

7 个答案:

答案 0 :(得分:46)

将行星对象添加到数组中,然后您可以编写:

Planet[] planets = {planet1, planet2, planet3, planet4, planet5};

for (int i = 0; i < star.returnZones(); i++) {
    this.createPlanet(planets[i], star);
}

答案 1 :(得分:44)

执行此操作的一种方法是switch语句,其中包含后果行为:

switch (star.returnZones()) {
    case 5: this.createPlanet(planet5, star); // fall-through
    case 4: this.createPlanet(planet4, star); // fall-through
    case 3: this.createPlanet(planet3, star); // fall-through
    case 2: this.createPlanet(planet2, star); // fall-through
    case 1: this.createPlanet(planet1, star); // fall-through
}

由于缺少break语句可以实现性能降低,因此强烈建议添加澄清注释,如上所示,以便读者立即了解丢失的break陈述是故意的。

缺点是它会以相反的顺序创建行星。

另一种选择是循环:

Planet[] planet={ planet1, planet2, planet3, planet4, planet5 };
int number = star.returnZones();
if(number>0 && number<=5) {
    for(int pIndex=0; pIndex<number; pIndex++)
        this.createPlanet(planet[pIndex], star);
}

请注意,在任何一种情况下,您都应该考虑范围之外的值应该发生什么。如果您认为这种情况永远不会发生,那么您应该添加一个代码,如果违反该假设,将抛出错误,以确保立即检测到不一致或损坏的数据,而不是继续用户可能会报告为“奇怪的行为”(没有关于问题真正根源的线索,例如

switch (star.returnZones()) {
    default: throw new AssertionError("returnZones should be 1..5");
    case 5: this.createPlanet(planet5, star); // fall-through
    case 4: this.createPlanet(planet4, star); // fall-through
    case 3: this.createPlanet(planet3, star); // fall-through
    case 2: this.createPlanet(planet2, star); // fall-through
    case 1: this.createPlanet(planet1, star); // fall-through
}

Planet[] planet={ planet1, planet2, planet3, planet4, planet5 };
int number = star.returnZones();
if(number>0 && number<=5) {
    for(int pIndex=0; pIndex<number; pIndex++)
        this.createPlanet(planet[pIndex], star);
}
else throw new AssertionError("returnZones should be 1..5");

答案 2 :(得分:10)

您也可以使用名为createPlanets(PlanetCreator creator, Star star, Planet...planets)的varags静态方法。

然后你所要做的就是将你的行星作为一个数组传递或用逗号分隔(最后仍是数组)并循环遍历它们:

public static void createPlanets(PlanetCreator creator, Star star, Planet...planets) {
    for (Planet p: planets) {
        creator.createPlanet(p, star);
    }
}

答案 3 :(得分:10)

还有另一种类似于@ njzk2答案第一部分的解决方案:switch/case 通过

int zones = star.returnZones();
switch (zones ) {
 case 5:
    createPlanet(planet5, star);
 case 4:
    createPlanet(planet4, star);
 case 3:
    createPlanet(planet3, star);
 case 2:
    createPlanet(planet2, star);
 default:
    createPlanet(planet1, star);   
}

答案 4 :(得分:10)

其他答案是正确的,这样的重复性工作可以通过循环整齐地处理。

使用 Java 8 还有另一个,可以说是更整洁的选项 - 使用Stream API以功能样式声明重复性工作。你可以用一行完成整个事情。

Arrays.asList(planet1, planet2, planet3 /*...etc*/)
  .stream()
  .limit(star.returnZones())
  .forEach((planet) -> this.createPlanet(planet, star));

请注意,前3行只是为了说明长度为 n 行星的流的设置 - 这可以而且应该由另一种方法动态完成,而不是像这样静态定义,进一步简化。

答案 5 :(得分:8)

问题陈述有时会引导解决方案。在您的情况下,您需要重复类似的任务。对于每个任务,都有一个不同的planet,但它又遵循一个订单。这个问题可以通过循环轻松解决。

一个简单的解决方案是将对象planet1planet2,... planet3放在ArrayList中。然后使用for循环迭代star.returnZones()次并在每次迭代中调用createPlanet,从ith迭代的数组列表中传递ith项。

答案 6 :(得分:7)

只是阵列的一个小变化回答:

List<Planet> planets = Arrays.asList(planet1, planet2, planet3 /*etc*/);
for (Planet p : planets.subList(0, start.returnZones()) {
  createPlanet(p, star);
}