Kotlin开发Minecraft服务器:寻找替代if/else的可配置代码模式
优化Minecraft服务器配置驱动逻辑的编程模式
我正在用Kotlin开发Minecraft服务器,现在遇到个问题:对于用户可配置的机制,有没有比一堆if/else更优雅的写法?
比如这段控制玩家直接控制模式的代码,里面已经有一个配置项dcDrift控制是否传送玩家:
fun setDirectControlEnabled(enabled: Boolean) { isDirectControlEnabled = enabled if (enabled) { sendMessage(dcMessage) val player: Player = (controller as? PlayerController)?.player ?: return player.walkSpeed = 0.009f val playerLoc = player.location directControlCenter = playerLoc.toBlockLocation().add(0.5, playerLoc.y.rem(1)+0.001, 0.5) if(!PlayerCache[player].playerConfig.dcDrift) { // 配置项检查 player.teleport(directControlCenter!!) } // 更多代码... } }
但随着配置项增多,代码会变成嵌套的if/else地狱,比如:
if (configOne) { // 执行操作 if (configTwo) { // 额外操作 } } else { // 执行替代操作 }
试过装饰器和注解,但不太适用,求能减少代码混乱的模式。
1. 策略模式 + 配置映射
把不同配置对应的行为封装成独立的策略类,用配置值直接匹配策略,彻底剥离条件判断。
比如针对直接控制的传送逻辑:
// 定义策略接口 interface TeleportStrategy { fun execute(player: Player, center: Location) } // 实现不同策略 class TeleportToCenter : TeleportStrategy { override fun execute(player: Player, center: Location) = player.teleport(center) } class NoTeleport : TeleportStrategy { override fun execute(player: Player, center: Location) = Unit // 什么都不做 } // 配置到策略的映射 fun getTeleportStrategy(config: PlayerConfig): TeleportStrategy { return if (config.dcDrift) NoTeleport() else TeleportToCenter() } // 重构后的调用代码 fun setDirectControlEnabled(enabled: Boolean) { isDirectControlEnabled = enabled if (enabled) { sendMessage(dcMessage) val player: Player = (controller as? PlayerController)?.player ?: return player.walkSpeed = 0.009f val playerLoc = player.location directControlCenter = playerLoc.toBlockLocation().add(0.5, playerLoc.y.rem(1)+0.001, 0.5) // 直接用策略执行,无if判断 getTeleportStrategy(PlayerCache[player].playerConfig) .execute(player, directControlCenter!!) // 其他逻辑... } }
新增配置时,只需要加新的策略类和映射规则,主逻辑保持干净。
2. Kotlin扩展函数 + 配置条件执行
把配置判断和行为绑定成扩展函数,让代码读起来像自然语言,把配置检查从主逻辑中剥离。
// 给PlayerConfig加扩展函数,封装条件行为 fun PlayerConfig.withDcDriftDisabled(action: () -> Unit) { if (!this.dcDrift) action() } // 重构后的主逻辑 fun setDirectControlEnabled(enabled: Boolean) { isDirectControlEnabled = enabled if (enabled) { sendMessage(dcMessage) val player: Player = (controller as? PlayerController)?.player ?: return player.walkSpeed = 0.009f val playerLoc = player.location directControlCenter = playerLoc.toBlockLocation().add(0.5, playerLoc.y.rem(1)+0.001, 0.5) // 直接调用扩展函数,语义清晰 PlayerCache[player].playerConfig.withDcDriftDisabled { player.teleport(directControlCenter!!) } // 其他逻辑... } }
这种方式适合简单的配置条件,新增配置时只需要加对应的扩展函数即可。
3. 配置驱动的动作列表
把所有配置对应的动作组织成一个列表,遍历执行符合条件的动作,彻底消除if/else。
比如把直接控制模式下的所有配置动作列出来:
fun setDirectControlEnabled(enabled: Boolean) { isDirectControlEnabled = enabled if (enabled) { sendMessage(dcMessage) val player: Player = (controller as? PlayerController)?.player ?: return val config = PlayerCache[player].playerConfig val playerLoc = player.location directControlCenter = playerLoc.toBlockLocation().add(0.5, playerLoc.y.rem(1)+0.001, 0.5) // 定义带条件的动作对象 data class ConfigAction(val condition: () -> Boolean, val action: () -> Unit) // 配置动作列表 val actions = listOf( ConfigAction({ true }) { player.walkSpeed = 0.009f }, ConfigAction({ !config.dcDrift }) { player.teleport(directControlCenter!!) }, ConfigAction({ config.someOtherSetting }) { doSomething() } ) // 执行所有符合条件的动作 actions.filter { it.condition() }.forEach { it.action() } } }
这种方式适合大量独立的配置动作,主逻辑只负责定义和执行动作,配置判断和动作绑定在一起,结构清晰易维护。
4. 使用Kotlin的when表达式替代嵌套if
如果配置项是枚举类型或者有限的离散值,用when表达式比嵌套if更清晰:
比如如果配置是枚举:
enum class DcDriftMode { ENABLED, DISABLED, PARTIAL } // 重构后 when (config.dcDriftMode) { DcDriftMode.DISABLED -> player.teleport(directControlCenter!!) DcDriftMode.PARTIAL -> player.teleport(directControlCenter!!.add(0.0, 0.5, 0.0)) DcDriftMode.ENABLED -> Unit }
when表达式支持多分支,比嵌套if更易读,也更容易扩展新的配置值。
内容的提问来源于stack exchange,提问作者Consuelo Ugarte
相关产品推荐
相关产品推荐

