将条件移动到类时出错

时间:2015-04-17 09:10:15

标签: java refactoring

我正在开发一个涉及实现一些重构技术的硬件,我遇到了一个我似乎无法发现的错误。我有以下方法,最初在Fish类中,我移动到一个名为Strategy

的类中
public class Strategy
{
    public void move (Fish fish, Pond pond)
    {
        if (fish.getHunger() < 0.2)
        {
            if (fish.getSize() < 7.0)
            {
                double[] location = pond.findNearestPlant(fish.getX(), fish.getY());
                fish.swimTowards(location[0], location[1]);
            }
            else
            {
                double[] location = pond.findNearestSmallFish(fish.getX(), fish.getY());
                fish.swimTowards(location[0], location[1]);
            }
        }
        else
        {
            // There are more conditionals in this block.  I haven't done anything with them yet so I didn't put them in.
        }
    }
}

我试图将if块中的条件转换为2个单独的类,这些类也位于我的Strategy.java文件中。

class SmallFish extends Strategy
{
    public void move (Fish fish, Pond pond)
    {
        double[] location = pond.findNearestPlant(fish.getX(), fish.getY());
        fish.swimTowards(location[0], location[1]);
    }
}

class BigFish extends Strategy
{
    public void move (Fish fish, Pond pond)
    {
        double[] location = pond.findNearestSmallFish(fish.getX(), fish.getY());
        fish.swimTowards(location[0], location[1]);
    }
}

回到Fish课程中,我添加了几行代码来确定要调用的类:

import java.lang.Math;
import java.util.Random;

public class Fish
{
    private static Random random = new Random();
    private static int numberOfFish = 0;

    private double hunger;
    private double size;
    private double x;
    private double y;
    private int id;

    // I added this line
    private Strategy strategy;

    private FishReport myFishReport = null;

    public Fish(double x, double y, FishReport report)
    {
        hunger = 0.9;
        size = 1.0;

        // Put it in the pond
        this.x = x;
        this.y = y;

        id = numberOfFish;
        numberOfFish++;

        // I added this code
        if (hunger < 0.2 && size < 7.0)
            this.strategy = new SmallFish();
        else if (hunger < 0.2 && size >= 7.0)
            this.strategy = new BigFish();
        else
            this.strategy = new Strategy();

        myFishReport = report;
        if(myFishReport != null)
        {
            myFishReport.updateHunger(hunger);
            myFishReport.updateSize(size);
            myFishReport.updateLocation(x, y);
        }
    }

    public void age(double timePassed)
    {
        double deltaSize = size * (1 + hunger * Math.exp(-size * timePassed));
        size = size + deltaSize;

        hunger = hunger * Math.exp(-deltaSize/size);

        myFishReport.updateHunger(hunger);
        myFishReport.updateSize(size);   
    }

    public void move(Pond pond)
    {
        strategy.move(this, pond);
    }

    // More methods below that I did not touch.  Left out to keep code as short as possible.
}

我添加SmallFish课后,我的测试套件仍然通过,但是在添加BigFish类后我失败了:

  

JUnit测试结果:
  testMoveStarving(FishTests):饥饿的鱼应该移动预期:&lt; 10.2981&gt;但是:&lt; 10.3965129880783&gt;
  总测试次数:8
  失败总数:1

以下测试失败:

public void testMoveStarving()
{
    // Create a new fish and report
    FishReport report = new FishReport();
    Fish fish = new Fish(10, 20, report);

    // Make a pond
    Pond pond = new Pond();

    // Grow the fish until starving
    fish.age(20);
    fish.age(20);
    fish.age(20);
    fish.age(20);

    // Move the fish, and check the new location
    fish.move(pond);

    // Check the new location
    assertEquals("Starving fish should move", 10.2981, report.getLocation()[0], 0.001);
    assertEquals("Starving fish should move", 20.5963, report.getLocation()[1], 0.001);
}

我唯一能想到的是BigFish构造函数中Fish类的条件不准确。我一直盯着这个看了一个多小时,所以我觉得我只需要另外一双眼睛指出我哪里出错了。如果有一些更极端的东西,那么只是Fish构造函数中的条件,请尝试给出提示而不是答案。就像我说的,这是硬件分配的一部分。

先谢谢你

编辑1 - 我忘了在move()课程中添加更改后的Fish方法。现在已经修好了。

编辑2 - 已发布失败测试。该测试调用age()类中的Fish方法,因此我也添加了该方法。

1 个答案:

答案 0 :(得分:1)

不知道代码的其余部分是什么样的,但如果鱼的sizehunger在构建后发生变化,您将不再使用正确的策略。 (目前,您的所有鱼类都将使用Strategy策略,BigFishSmallFish都没有。)

将策略选择保留在move方法而不是构造函数中可能更有意义。