iT邦幫忙

2022 iThome 鐵人賽

0

有一陣子沒有更新了,最近有一些心得來補充一下。

為什麼要使用 Value Class,有寫在另一篇 https://ithelp.ithome.com.tw/m/articles/10292720 。主要就是原始型別,有機會塞錯,所以用 value class 確保,並且達到 Domain Design。所以我們把原始型別都建立一個 inline value type, 並且也把 mongodb 的 key 用 get 寫在這。
https://github.com/hmchangm/getting-start-QK/blob/master/src/main/kotlin/tw/brandy/ironman/entity/Film.kt

@JvmInline
value class Title(val raw: String) {
    companion object {
        val key get() = "title"
    }
}

@JvmInline
value class Director(val raw: String) {
    companion object {
        val key get() = "director"
    }
}

UUID 的處理

@JvmInline
value class EpisodeId(private val s: UUID) {
    val raw get() = s.toString()

    companion object {
        fun from(str: String): Either<WrongUUIDFormat, EpisodeId> {
            return Either.catch {
                EpisodeId(UUID.fromString(str))
            }.mapLeft {
                WrongUUIDFormat(str)
            }
        }
        val key get() = "episodeId"
    }
}

DateTime Wrapper

@JvmInline
value class ReleaseDate(val raw: Date) {
    companion object {
        val formatter = SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH)
        val key get() = "releaseDay"

        fun fromIsoDate(iso: String): ReleaseDate {
            return ReleaseDate(formatter.parse(iso))
        }
    }
}

Data Class with inline fields

data class Film(
    val episodeId: EpisodeId,
    val title: Title,
    val director: Director,
    val releaseDate: ReleaseDate
)

在 DAO 作 collection type transformation

    val from: suspend (Document) -> Either<AppError, Film> = { doc ->
        either {
            Film(
                doc.getString(EpisodeId.key).let { EpisodeId.from(it) }.bind(),
                Title(doc.getString(Title.key)),
                Director(doc.getString(Director.key)),
                ReleaseDate(doc.getDate(ReleaseDate.key))
            )
        }
    }

    val to: suspend (Film) -> Document = { film ->
        Document().apply {
            append(EpisodeId.key, film.episodeId.raw)
            append(Title.key, film.title.raw)
            append(Director.key, film.director.raw)
            append(ReleaseDate.key, film.releaseDate.raw)
        }
    }

上一篇
第三十天 - Quarkus 與 Kotlin 回顧與未盡 - Redis, Kafka, S3..
下一篇
Kotlin Inline Value Class 與 Jackson Json Serialization
系列文
Quarkus, Kotlin, Reactive 雲原生服務開發32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言