cy
05/26/2017, 3:13 PMdata class Color(val r: Int, val g: Int, val b: Int) {
init {
require(r in 0..255) { "invalid red $r" }
require(g in 0..255) { "invalid red $g" }
require(b in 0..255) { "invalid red $b" }
}
constructor(r: String, g: String, b: String) : this(r.toColorComponent("red"),
g.toColorComponent("green"),
b.toColorComponent("blue"))
}
private fun String.toColorComponent(name: String) = toIntOrNull() ?: throw IllegalArgumentException("Color component $name string is not a number: $this")
pawel.barszcz
05/26/2017, 3:14 PMcy
05/26/2017, 3:14 PMpawel.barszcz
05/26/2017, 3:14 PMActivityId
kevinherron
05/26/2017, 3:16 PMcy
05/26/2017, 3:16 PMpawel.barszcz
05/26/2017, 3:16 PMinit { ...}
before asking more questionsinit { ... }
and I will come back if I see some real disadvantages of using it 🙂data class ActivityName private constructor(
val value: String
) {
companion object {
const val MAX_NAME_LENGTH: Int = 1_000
fun of(value: String?): ActivityName {
if (value == null) throw ActivityNameIsEmptyException()
return value.trim().let {
if (it.isEmpty()) throw ActivityNameIsEmptyException()
if (it.length > MAX_NAME_LENGTH) throw ActivityNameIsTooLongException()
ActivityName(it)
}
}
}
}
In other words: I want to provide possibility to construct my object from nullable String?
. Other way I would have to check for null outside the object, and check for emptiness inside the object, while both cases are in fact checking for semantical emptinessString
, and another one with String?
because of clashing signaturescy
05/26/2017, 3:35 PMActivityName
fun ActivityName(name: String?) = if (name == null) throw IlegalArgumentException("...") else ActivityName(name)
pawel.barszcz
05/26/2017, 3:37 PMdata class ActivityName(
val value: String
) {
// ...
}
fun ActivityName(value: String?) {
return ActivityName(value)
}
cy
05/26/2017, 3:38 PMreturn if (value != null) ActivityName(value) else throw
pawel.barszcz
05/26/2017, 3:39 PM// ... validation ehre
🙂ActivityName
function instead of data class. I mean it can be a bit confusing to operate on bothcy
05/26/2017, 3:40 PMpawel.barszcz
05/26/2017, 3:40 PMdon’t eliminate null safety, use itFor simplicity (even if I can make it better) let’s say that I don’t know whether my HTTP request body contains name of activity or not
ActivityName
, but then I will end up with checking for null in one palce and cheking for emptiness in anothercy
05/26/2017, 3:43 PMof
with nullable and constructor with non-nullof
and for empty in init
pawel.barszcz
05/26/2017, 3:46 PM#aabbcc
, #abc
, and #ABC
, but you want to to retrieve the value always normalized to lowercase, 6-charactersdata class ActivityColor private constructor(
val hexValue: String
) {
companion object {
// ...
fun of(hexValue: String?): ActivityColor {
// validation
return ActivityColor(normalized(hexValue))
}
// ...
}
}
.copy(...)
on data class)