You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 14:35:15