首页 > 解决方案 > KOTLIN:当条件子句与另一个子句结合时重构一个大回报

问题描述

'这是一个设计和技术代码方面的问题,所以在我对一个随机项目进行一些重构以使其更新时,我遇到了以下部分,一个密封类上的中缀函数正在执行某种验证:

infix fun TaskState.allowsOperation(operation: TaskOperation): Boolean {
    return when (this) {
        TaskState.Scheduled -> {
            when (operation) {
                TaskOperation.Start -> true
                TaskOperation.Stop -> false
                TaskOperation.Pause -> false
                TaskOperation.Resume -> false
            }
        }
        TaskState.Running -> {
            when (operation) {
                TaskOperation.Start -> false
                TaskOperation.Stop -> true
                TaskOperation.Pause -> true
                TaskOperation.Resume -> false
            }
        }
        TaskState.Stopped -> {
            when (operation) {
                TaskOperation.Start -> false
                TaskOperation.Stop -> false
                TaskOperation.Pause -> false
                TaskOperation.Resume -> false
            }
        }
        TaskState.Suspended -> {
            when (operation) {
                TaskOperation.Start -> false
                TaskOperation.Stop -> true
                TaskOperation.Pause -> false
                TaskOperation.Resume -> true
            }
        }
        TaskState.Terminated -> {
            when (operation) {
                TaskOperation.Start -> true
                TaskOperation.Stop -> false
                TaskOperation.Pause -> false
                TaskOperation.Resume -> false
            }
        }
        TaskState.Created -> {
            when (operation) {
                TaskOperation.Start -> true
                TaskOperation.Stop -> false
                TaskOperation.Pause -> false
                TaskOperation.Resume -> false
            }
        }
    }
}

所以基本上,发生了什么是糖语法添加,它允许在其他部分像这样调用代码:

if (task.state allowsOperation operation) doSomething()

但是,我发现那堆特定的代码看起来很难看,我想不出另一种合理的方法来做这件事,但同时又不会产生太多的变化。

TaskState 和 TaskOperation 只是一些密封类:

sealed class TaskState {
    object Created : TaskState()
    object Scheduled : TaskState()
    object Running : TaskState()
    object Stopped : TaskState()
    object Terminated : TaskState()
}
sealed class TaskOperation {
    object Start : TaskOperation()
    object Stop : TaskOperation()
    object Pause : TaskOperation()
    object Resume : TaskOperation()
}

你对如何重构这种类型的东西有什么建议吗?

标签: kotlinrefactoringsealed-class

解决方案


这些没有理由成为密封类,因为每个子类都是一个object,并且它们都没有任何不同的参数。只需使用枚举,但您必须在其中一个使用语句is的地方删除所有关键字。when

TaskState您可以通过为类提供允许操作的参数来简化代码量。这可以替换您上面的所有内容。

enum class TaskOperation {
    Start, Stop, Pause, Resume
}

enum class TaskState(private vararg val allowableOperations: TaskOperation) {
    Scheduled(TaskOperation.Start),
    Running(TaskOperation.Stop, TaskOperation.Pause),
    Stopped(),
    Suspended(TaskOperation.Stop, TaskOperation.Resume),
    Terminated(TaskOperation.Start);

    infix fun allowsOperation(operation: TaskOperation) = operation in allowableOperations
}

infix此外,这是一种观点,但我认为如果函数不加入或比较两件事,那么使用它是愚蠢和糟糕的。


推荐阅读