Я бы хотел сказать, что использование одного компоновщика небезопасно для построения нескольких типов. Было бы лучше разделить его на определенные c классы, возможно, с некоторым общим базовым классом. Итак, мой ответ:
Классы моделей
open class BaseModel(val icon: Int, val background: Int)
class ProductModel(val title: String, val description: String, icon: Int, background: Int) : BaseModel(icon, background)
class SalesModel(val title: String, val description: String, icon: Int, background: Int) : BaseModel(icon, background)
Строители
abstract class BaseBuilder<T : BaseModel> {
abstract var icon: Int
abstract var background: Int
abstract fun build(): T
}
class ProductBuilder : BaseBuilder<ProductModel>() {
override var icon = 222222
override var background = 444444
var title = ""
var description = ""
override fun build() = ProductModel(title, description, icon, background)
}
class SalesBuilder : BaseBuilder<SalesModel>() {
override var icon = 111111
override var background = 333333
var title = ""
var description = ""
override fun build() = SalesModel(title, description, icon, background)
}
И, наконец, Маркетинговый класс
class Marketing {
companion object {
fun buildProduct(filler: ProductBuilder.() -> Unit) : ProductModel {
return ProductBuilder().run {
filler()
build()
}
}
fun buildSales(filler: SalesBuilder.() -> Unit) : SalesModel {
return SalesBuilder().run {
filler()
build()
}
}
}
}
Таким образом, вы можете легко и безопасно создавать модели:
val product = Marketing.buildProduct {
title = "title"
description = "descr"
}
Обязательное поле
Если вы хотите сделать какое-либо свойство неизменяемым, вы можете заменить его из свойства var
в конструктор на val
. Пример для title
свойство:
Builder
class ProductBuilder(val title: String) : BaseBuilder<ProductModel>() {
override var icon = 111111
override var background = 333333
var description = ""
override fun build() = ProductModel(title, description, icon, background)
}
Builder вызывает
fun buildProduct(title: String, filler: ProductBuilder.() -> Unit) : ProductModel {
return ProductBuilder(title).run {
filler()
build()
}
}
Использование
val product = Marketing.buildProduct("title") {
//title = "title" - this line wouldn't be compiled anymore
description = "descr"
}