如何简化这个Java代码?

时间:2015-07-25 21:29:38

标签: java conditional simplify

我正在为一个名为Spigot(spigotmc.org)的Minecraft服务器软件编写一些Java代码,我刚刚写了这篇文章。目标是检查变量block的每一侧,并检查墙上的标志,如您所见。它应该只需要找到一个。然后它会更新它和诸如此类的东西。我知道这段代码可以简化,但目前我无法看到如何在条件语句中为代码创建一个全新的函数,这是我不想做的。有没有更好的方法来写这个条件?

// Get an attached sign
Block sign;
if ((sign = block.getRelative(BlockFace.NORTH)).getType() == Material.WALL_SIGN) {
    org.bukkit.block.Sign data = (Sign) sign.getState();
    data.setLine(1, "OFF");
    data.update();
} else if ((sign = block.getRelative(BlockFace.EAST)).getType() == Material.WALL_SIGN) {
    org.bukkit.block.Sign data = (Sign) sign.getState();
    data.setLine(1, "OFF");
    data.update();
} else if ((sign = block.getRelative(BlockFace.WEST)).getType() == Material.WALL_SIGN) {
    org.bukkit.block.Sign data = (Sign) sign.getState();
    data.setLine(1, "OFF");
    data.update();
} else if ((sign = block.getRelative(BlockFace.SOUTH)).getType() == Material.WALL_SIGN) {
    org.bukkit.block.Sign data = (Sign) sign.getState();
    data.setLine(1, "OFF");
    data.update();
}

3 个答案:

答案 0 :(得分:2)

也许是一个循环?

// Get an attached sign
Block sign;
BlockFace[] faces = new BlockFace[] {
    BlockFace.NORTH,
    BlockFace.EAST,
    BlockFace.WEST,
    BlockFace.SOUTH};

for(BlockFace face : faces) {
    if ((sign = block.getRelative(face)).getType() == Material.WALL_SIGN) {
        org.bukkit.block.Sign data = (Sign) sign.getState();
        data.setLine(1, "OFF");
        data.update();
        break;
    }
}

当您有许多选项需要查看时,此方法很有效。另外,如果你在其他地方做类似的逻辑,肯定会创建一个函数,所有具有相同需求的客户端都可以调用它!

答案 1 :(得分:2)

根据DRY原则,您需要重复使用重复部分。在你的例子中,整个if块是相同的,除了face。

  1. 用for:

    替换ifs
    List<BlockFace> blockFaces = Arrays.asList(BlockFace.NORTH, BlockFace.EAST, BlockFace.WEST, BlockFace.SOUTH);
    for (BlockFace face : blockFaces) {
        Sign sign = block.getRelative(face);
        if (sign.getType() == Material.WALL_SIGN) {
            org.bukkit.block.Sign data = (Sign) sign.getState();
            data.setLine(1, "OFF");
            data.update();
            break;
        }
    }
    
  2. 提取方法:

    private boolean updateAttachedSign(Block block, BlockFace face) {
        Sign sign = block.getRelative(face);
        if (sign.getType() == Material.WALL_SIGN) {
            org.bukkit.block.Sign data = (Sign) sign.getState();
            data.setLine(1, "OFF");
            data.update();
            return true;
        }
        return false;
    }
    
    {
        boolean signIsUpdated =
            updateAttachedSign(block, BlockFace.NORTH) ||
            updateAttachedSign(block, BlockFace.EAST) ||
            updateAttachedSign(block, BlockFace.WEST) ||
            updateAttachedSign(block, BlockFace.SOUTH);
    }
    
  3. 第二种解决方案,尽管一般来说是优越的方法,但对你的情况来说似乎有点过于复杂。我坚持使用第一个。

    @Constantin编辑:

    谨慎使用短路条件。请参阅这篇有用的帖子https://softwareengineering.stackexchange.com/questions/284415/short-circuit-evaluation-is-it-bad-practice

答案 2 :(得分:1)

您的内部if范围始终相同,因此您可以在条件之间使用“或”命令:

// Get an attached sign
Block sign;
if (((sign = block.getRelative(BlockFace.NORTH)).getType() == Material.WALL_SIGN) 
 || ((sign = block.getRelative(BlockFace.EAST)).getType()  == Material.WALL_SIGN)
 || ((sign = block.getRelative(BlockFace.WEST)).getType()  == Material.WALL_SIGN)
 || ((sign = block.getRelative(BlockFace.SOUTH)).getType() == Material.WALL_SIGN)
    org.bukkit.block.Sign data = (Sign) sign.getState();
    data.setLine(1, "OFF");
    data.update();
}