java - 如何避免重复?

标签 java

<分区>

我使用 Java 并尝试在不同的情况下为不同的事物分配不同的任务,但有时它们会做同样的事情。这会导致一些重复(实际上是长行,而不是短方法名称),但是有没有一种简单的方法可以避免这些重复?

if(direction == Direction.UP) {
    doThingA(); // same thing as down
    doCustomThing1();
    doSameThing(); // all do this
    doCustomThing5();
} else if(direction == Direction.DOWN) {
    doThingA();
    doCustomThing2();
    doSameThing();
    doCustomThing6();
} else if(direction == Direction.RIGHT) {
    doThingB() // same thing as left
    doCustomThing3();
    doSameThing();
    doCustomThing7();
} else if(direction == Direction.LEFT) {
    doThingB()
    doCustomThing4();
    doSameThing();
    doCustomThing8();
}

这是真正的代码,正如您所看到的,自定义的东西只是略有不同,但我不知道如何简化它:

if(direction == Direction.UP) {
    box.setAsBox(size.value/2, Constants.WORLD_HEIGHT/2);
    bodyDef.position.set(new Vector2(rand.nextFloat()*(Constants.WORLD_WIDTH-size.value)+size.value/2, -Constants.WORLD_HEIGHT*0.5f));
    body = gameWorld.world.createBody(bodyDef);
    body.setLinearVelocity(new Vector2(0f, 5f));
} else if(direction == Direction.DOWN) {
    box.setAsBox(size.value/2, Constants.WORLD_HEIGHT/2);
    bodyDef.position.set(new Vector2(rand.nextFloat()*(Constants.WORLD_WIDTH-size.value)+size.value/2, Constants.WORLD_HEIGHT*1.5f));
    body = gameWorld.world.createBody(bodyDef);
    body.setLinearVelocity(new Vector2(0f, -5f));
} else if(direction == Direction.RIGHT) {
    box.setAsBox(Constants.WORLD_WIDTH/2, size.value/2);
    bodyDef.position.set(new Vector2(-Constants.WORLD_WIDTH*0.5f, rand.nextFloat()*(Constants.WORLD_HEIGHT-size.value)+size.value/2));
    body = gameWorld.world.createBody(bodyDef);
    body.setLinearVelocity(new Vector2(5f, 0f));
} else if(direction == Direction.LEFT) {
    box.setAsBox(Constants.WORLD_WIDTH/2, size.value/2);
    bodyDef.position.set(new Vector2(Constants.WORLD_WIDTH*1.5f, rand.nextFloat()*(Constants.WORLD_HEIGHT-size.value)+size.value/2));
    body = gameWorld.world.createBody(bodyDef);
    body.setLinearVelocity(new Vector2(-5f, 0f));
}

最佳答案

当我看到枚举作为 switch 语句或 if-else 阶梯中的条件,并且编写控制语句的人拥有该枚举时,我认为这是一种代码味道。

考虑这个替代方案,而不是打开枚举,为什么不使用你在其他地方做的同样的事情呢?我建议你在这里试试多态性。

首先,如果您没有对枚举有意义的默认实现,请使用一些抽象方法定义您的方向枚举。这与下面示例中的 getWidth() 相同。

其次,添加任何您可能需要的具有合理默认值的非抽象方法。然后,您可以像在普通 Java 多态性中那样覆盖这些方法。这与下面示例中的 getHeight() 相同。

这种方法有很多优点。

  1. 如果您想添加更多方向(假设您从 4 个方向变成了 8 个方向,添加了左上、右上、右下、左下),那么您不必遍历整个代码基础并添加其他 if-else 语句。您只需在枚举中为这些新方向添加特定于实现的代码即可。一切正常。
  2. 添加默认行为非常简单,您不必在代码库的多个位置保持同步。
  3. 您的调用代码中的代码行会随着您拥有的枚举数的增加而减少。如果您有 10 个枚举,并且必须为每个枚举编写 10 次调用,那么您将有 121 行代码(计算调用和控制语句),但是在您开始使用多态性之后,您将有 10 行代码(没有控制语句,只有方法调用)。这应该会降低您的圈复杂度。
  4. 您清楚地将枚举的功能封装在枚举本身中。在这里你必须要小心一点,如果你对这种方法发疯,枚举最终可能会了解系统的太多部分,但通常我发现这不是问题。

方向枚举

public enum Direction {
    UP {
        public int getWidth() {
            return 50;
        }
        @Override
        public int getHeight() {
            return 100;
        }
    },
    DOWN {
        public int getWidth() {
            return 30;
        }
    };

    public abstract int getWidth();
    public int getHeight() {
        return 10;
    }
}

现在你的调用代码看起来像这样。

box.setAsBox(direction.getWidth(), direction.getSize());
bodyDef.position.set(direction.getPositionVector());
body = gameWorld.world.createBody(direction.getBody());
body.setLinearVelocity(direction.getLinearVelocity());

关于java - 如何避免重复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34486528/

相关文章:

java - 从 Scanner 替换文件中的一行

java - Firebase 值未更新

java - 如何在 Java/Groovy 中测试 MongoDB 过滤器 (BSON) 的相等性?

java - Spring MVC 无法访问 Tomcat 上的应用程序

java - 给定一个整数 N 作为输入,您可以检查以下内容 :

java - Cmd :FAILURE: Build failed with an exception 中的 Gradlew 和 Java 9

Java:system.out.println 连接字符串中的内容(非常简单的问题)

java - 我的 (Java/Swing) MouseListener 没有监听,请帮我找出原因

java - 适用于所有 Android 版本的通用 Android 对象样式?

java - 如何使用opencv检测脖子、手腕和耳朵?