我正在为一个名为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();
}
答案 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。
用for:
替换ifsList<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;
}
}
提取方法:
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);
}
第二种解决方案,尽管一般来说是优越的方法,但对你的情况来说似乎有点过于复杂。我坚持使用第一个。
按@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();
}