Java 的 Record 類是從 Java 16 開始提供的新特性,提供了一種簡潔的方式來建立不可變的資料類別。而在 Kotlin 早已經有 data class 這樣的功能來達到相似的效果。
一開始接觸到 Kotlin 的 data class 以為他是為了簡化 POJO 的宣告與樣版程式碼的減少。學了 functional programming 後才知道這是從 ADTs 的理論基礎來的。對比於與昨天 Sealed Interface 與 Domain Model 的 enum 與 sealed class 是和型別 (sum type),今天要談的 Data class 就是積型別 product type.
代數數據類型(algebraic data type,縮寫ADT)是一種複合類型,指由其他資料類型組合而成的類型,在程式語中中,尤其是函數式程式設計和類型論中應用。兩類常見的代數類型是
因為 Data Type 的值的可能性就是 field1 * field2 * field3的可能性,所以叫作 product type
退一個點講, Kotlin 中提供的數組(tuple) Pair<A,B>, Triple<A,B,C> 也是積類型
Sealed 與 Enum 都代表著可以列舉的可能性,所以是 1+1+1+... 稱作合類型
例如,考慮以下的 data class:
data class Person(val name: String, val age: Int)
這裡的 Person 型別就是 String 和 Int 的 product type。你可以認為它是 String 和 Int 的"乘積",因為每個 Person 實例都會有一個 String 型別的 name 和一個 Int 型別的 age。
函數式領域建模的目標是為了精確地的業務領域,以達到更高的型別安全性,最大化利用編譯器在我們的領域中,從而預防錯誤並減少單元測試。此外,由於領域是與真實世界的接觸點,因此使得關於領域的溝通變得更容易。Kotlin 很適合用於功能性領域模型。它提供了Data Class、Sealed Class、Enum 還有 Value Class
Kotlin 中 Value class 提供了原始資料型的封裝,這對於精準的領域建模也很重要。例如昨天的 Event 我們就可以引入 Value class 來避免欄位被放錯的問題。並且我們對於原始型別有了更精準的描述。
@JvmInline value class EventId(val value: Long)
@JvmInline value class Organizer(val value: String)
@JvmInline value class Title(val value: String)
@JvmInline value class Description(val value: String)
data class Event(
val id: EventId,
val title: Title,
val organizer: Organizer,
val description: Description,
val date: LocalDate
)
Help Me