我目前正在为一个AlarmTime示例设计一个整洁的数据类(模型),它将在Alarm类中扮演一个变量的角色。我提出了两个解决方案,我想知道哪一个更适合Kotlin约定,并且通常很适合这种情况。如果这两个想法都是错误的,我会非常感谢任何例子或指导你可以分享。
多谢了!
解决方案1
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
)
}
}
}
字符串
解决方案2
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())
}
}
型
1条答案
按热度按时间e3bfsja21#
我想挑战你的前提,即数据类非常适合你打算做的事情。
虽然没有明确说明,但从代码中看,您似乎希望确保不能创建无效的
AlarmTime
。这对数据类不起作用,因为您免费获得的东西之一是复制函数,它强制执行值的类型,但不执行验证。特别是以下代码编译并运行:字符串
这是解决方案1的问题,解决方案2更是如此-考虑将分钟设置为-1的示例:
型
如果没有特定的附加要求(例如equals/hashcode),我会选择解决方案1的简化变体
型