kotlin - 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()
}
你对如何重构这种类型的东西有什么建议吗?
解决方案
这些没有理由成为密封类,因为每个子类都是一个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
此外,这是一种观点,但我认为如果函数不加入或比较两件事,那么使用它是愚蠢和糟糕的。
推荐阅读
- c# - C# 和 Google 表格:离线模式
- karate - 如何在空手道 API 自动化项目中集成 Allure Report
- r - 将“整体”组添加到 facet_wrap (ggplot2)
- c - 按位与的结果似乎为 0,但不是
- excel - 使用 VBA 过滤多个组合
- mysql - Aws Rds 全局事件调度程序为超级管理员引发身份验证错误
- azure - 为什么 Azure SignalR 服务不提供诊断或日志?
- python - to_csv() 写入带有附加分数的值
- ruby - 从 ruby cucumber 输出 junit 时处理易碎测试(重试中断管道)
- xml - 在 XML 到 XML 的转换中使用 XSLT v1.0 进行连接