我目前正在为 AlarmTime 实例设计一个简洁的数据类(模型),它将在 Alarm 类中扮演变量的角色。我提出了两种解决方案,我希望得到一些建议来确定哪一种更适合 Kotlin 约定,并且通常更适合这种情况。如果这两个想法有很大偏差,我将非常感谢您可以分享的任何示例或指导。
非常感谢!
data class AlarmTime private constructor(
val hour: Int,
val minute: Int,
) {
fun toCombinedMinutes(): Int = hour * 60 + minute
companion object {
private const val MAX_COMBINED_MINUTES = 1439 // 23 * 60 + 59
operator fun invoke(hour: Int, minute: Int) =
when {
hour >= 24 || hour < 0 -> throw IllegalArgumentException(
"Invalid hour value. Hour must be within the range of 0 to 23.")
minute >= 60 || minute < 0 -> throw IllegalArgumentException(
"Invalid minute value. Minute must be within the range of 0 to 59.")
else -> AlarmTime(hour, minute)
}
operator fun invoke(combinedMinutes: Int) =
when {
combinedMinutes > MAX_COMBINED_MINUTES || combinedMinutes < 0 ->
throw IllegalArgumentException(
"Invalid combined minutes value. " +
"Combined minutes must be within the range of 0 to 1439"
)
else -> AlarmTime(
hour = combinedMinutes / 60,
minute = combinedMinutes % 60
)
}
}
}
data class Hour private constructor (val value: Int) {
companion object {
operator fun invoke(hour: Int) =
when {
hour >= 24 || hour < 0 -> throw IllegalArgumentException(
"Invalid hour value. Hour must be within the range of 0 to 23."
)
else -> Hour(hour)
}
}
}
data class Minute private constructor(val value: Int) {
companion object {
operator fun invoke(minute: Int) =
when {
minute >= 60 || minute < 0 -> throw IllegalArgumentException(
"Invalid minute value. Minute must be within the range of 0 to 59."
)
else -> Minute(minute)
}
}
}
data class CombinedMinutes(val value: Int) {
fun getHour(): Hour = Hour(this.value / 60)
fun getMinute(): Minute = Minute(this.value % 60)
companion object {
private const val MAX_COMBINED_MINUTES = 1439 // 23 * 60 + 59
operator fun invoke(combinedMinutes: Int) =
when {
combinedMinutes > MAX_COMBINED_MINUTES || combinedMinutes < 0 ->
throw IllegalArgumentException(
"Invalid combined minutes value. " +
"Combined minutes must be within the range of 0 to 1439"
)
else -> CombinedMinutes(combinedMinutes)
}
operator fun invoke(hour: Hour, minute: Minute) =
CombinedMinutes(hour.value * 60 + minute.value)
}
}
data class AlamTime2 private constructor(val hour: Hour, val minute: Minute) {
companion object {
operator fun invoke(hour: Hour, minute: Minute) =
AlamTime2(hour, minute)
operator fun invoke(combinedMinutes: CombinedMinutes) =
AlamTime2(combinedMinutes.getHour(), combinedMinutes.getMinute())
}
}
我想挑战你的前提,即数据类非常适合你想要做的事情。
虽然没有明确说明,但从您的代码来看,您似乎希望确保无法创建无效的
AlarmTime
。
这不适用于数据类,因为您免费获得的功能之一是 copy 函数,它强制执行值的类型,但不强制验证。特别是以下编译和运行:
AlarmTime(12,30).copy(minute = -1)
.also { println(it) } // AlarmTime(hour=12, minute=-1)