這更多是關于與域模型類相關的繼承的理論 Kotlin 問題。
讓我們考慮這種情況:我正在構建一個系統來處理圖書館的書籍,因此顯然需要某種book類。我可以使用資料類輕松創建它:
data class Book (val title: String, val author: String)
到目前為止,一切都很好。現在,該系統還處理預訂,這將是一個不同的模型,指定取貨地點和取貨日期,例如
data class ReservedBook(val title: String, val author: String, val location: String, val pickupDate: String)
所以,當然,ReservedBook類與類重疊Book,所以我在想最好的方法是讓它更易于維護和理解。
雖然我最初只是ReservedBook從Book類繼承,但 Kotlin 不允許資料類從其他資料類繼承,因為它搞砸了建構式/get/set 方法。
簡單的解決方案似乎包括Bookas 中的屬性ReservedBook,例如
data class ReservedBook(val book: Book, val location: String, val pickupDate: String)
很簡單,雖然在創建ReservedBook需要指定Book內部的實體時有點奇怪,例如
val newReservedBook = ReservedBook(Book("MyTitle", "MyAuthor"), "Location B", "20-10-2022")
因此,我在想是否有更聰明的方法來構建這樣的設定。我正在考慮創建一個名為BaseBook或類似的抽象類,然后讓所有更具體的資料類繼承自此,盡管撰寫這些類似乎有點麻煩:
abstract class BaseBook(
open val title: String,
open val author: String
)
data class ReservedBook(
override val title: String,
override val author: String,
val location: String,
val pickupDate: String
) : BaseBook(title, author)
然而,這使得創建新實體變得更加容易,因為您可以撰寫:
val newReservedBook = ReservedBook("MyTitle", "MyAuthor", "Location B", "20-10-2022")
所以,我很好奇人們認為處理這種情況的最佳方式是什么。也許你也有不同的提議?
uj5u.com熱心網友回復:
我認為@TheLibrarian 在對原始問題的評論中提出了一個很好的觀點。說為預訂制作一本新書很奇怪。
為了實作這個概念,我們使用了一些 Kotlin 最強大的工具。
具體來說,這是為了制作作為Traits操作的介面(這基于 Scala,但概念適用)
對于這種設計,將我們的代碼寫入介面而不是實作使我們能夠在我們的應用程式中非常自由地進行設計。
/** Interface for Books called IBook
* We define our [title] and [author] as you would expect
* We also utilize the power of a trait to give us an easy constructor for creating an [IReservedBook]
*/
interface IBook {
val title: String
val author: String
fun reserve(location: String, pickupDate: String): IReservedBook {
return ReservedBook(this, location, pickupDate)
}
}
/** Interface for reserved Books, which are [IBooks]
* We define our [location] and [pickupDate] without having to redeclare from [IBook]
*/
interface IReservedBook : IBook {
val location: String
val pickupDate: String
}
/** The actual class for [IBook] very straight forward */
data class Book(
override val author: String,
override val title: String
) : IBook
/** The actual class for [ReservedBook] where the magic starts to happen
* First, we take in an already existing instance of [IBook] - We want to develop around the interface rather than the
* actual to keep ourselves flexible. This helps us if we have multiple kinds of Books such as a PictureBook or a Reference
*
* Second, we override our base interface for the [IReservedBook]
*
* Next we specify how this actually fulfills [IBook]
* by using the `IBook by Book(book.author, book.title)`
*
* This gives us the best of both worlds by making sure a Book can become a ReservedBook, we also do not need to create
* a new instance of a Book to make it Reserved, and we maintain the freedom to introduce new books, as well as reservations
* without having any impact on our previous code.
*/
data class ReservedBook(
val book: IBook,
override val location: String,
override val pickupDate: String
) : IReservedBook, IBook by Book(book.author, book.title)
fun library() {
val importantBook = Book("A very impressive person", "Kotlin Rules")
val importantReservation = ReservedBook(importantBook, "Nimbus", "Tomorrow")
val popularBook = Book("Dracula", "20 ways to avoid garlic")
val popularReservation = popularBook.reserve("Transylvania", "Right now")
}
這種結構可以很好地構建和允許 Kotlin 鼓勵的組合,并保持簡單和流暢,從而為資訊提供廣闊的領域。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/519730.html
標籤:科特林哎呀遗产
上一篇:C -什么是虛擬方法?
