【问题标题】:KOTLIN: Refactoring a big return when conditional clause coupled with another oneKOTLIN:当条件子句与另一个子句结合时重构一个大回报
【发布时间】:2020-06-15 17:25:30
【问题描述】:

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

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()
}

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

【问题讨论】:

  • 请将您的代码添加为文本而不是图像。以这种方式在其他地方阅读或复制它要容易得多。此外,如果您的代码已经可以运行,并且您只是想让它更漂亮,您应该尝试在 Code Review Stack Exchange 上提出这个问题
  • 请参阅here,原因有很多,为什么发布代码图片不是一个好主意。
  • 感谢您的提示,我已经编辑并放置了文字,没想到。 :) 另外,实际上甚至都不知道代码审查堆栈交换-> 我正在继续。谢谢!

标签: kotlin refactoring sealed-class


【解决方案1】:

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

您可以通过为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 会很愚蠢且不利于可读性。

【讨论】:

    【解决方案2】:

    函数可以返回true的只有6种情况,有14种情况可以返回false

    在这种情况下,我们只能像这样处理true 分支:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多