How to implement Builder pattern in Kotlin?

后端 未结 13 1602
半阙折子戏
半阙折子戏 2020-11-29 16:18

Hi I am a newbie in the Kotlin world. I like what I see so far and started to think to convert some of our libraries we use in our application from Java to Kotlin.

T

13条回答
  •  粉色の甜心
    2020-11-29 17:00

    I have seen many examples that declare extra funs as builders. I personally like this approach. Save effort to write builders.

    package android.zeroarst.lab.koltinlab
    
    import kotlin.properties.Delegates
    
    class Lab {
        companion object {
            @JvmStatic fun main(args: Array) {
    
                val roy = Person {
                    name = "Roy"
                    age = 33
                    height = 173
                    single = true
                    car {
                        brand = "Tesla"
                        model = "Model X"
                        year = 2017
                    }
                    car {
                        brand = "Tesla"
                        model = "Model S"
                        year = 2018
                    }
                }
    
                println(roy)
            }
    
            class Person() {
                constructor(init: Person.() -> Unit) : this() {
                    this.init()
                }
    
                var name: String by Delegates.notNull()
                var age: Int by Delegates.notNull()
                var height: Int by Delegates.notNull()
                var single: Boolean by Delegates.notNull()
                val cars: MutableList by lazy { arrayListOf() }
    
                override fun toString(): String {
                    return "name=$name, age=$age, " +
                            "height=$height, " +
                            "single=${when (single) {
                                true -> "looking for a girl friend T___T"
                                false -> "Happy!!"
                            }}\nCars: $cars"
                }
            }
    
            class Car() {
    
                var brand: String by Delegates.notNull()
                var model: String by Delegates.notNull()
                var year: Int by Delegates.notNull()
    
                override fun toString(): String {
                    return "(brand=$brand, model=$model, year=$year)"
                }
            }
    
            fun Person.car(init: Car.() -> Unit): Unit {
                cars.add(Car().apply(init))
            }
    
        }
    }
    

    I have not yet found a way that can force some fields to be initialized in DSL like showing errors instead of throwing exceptions. Let me know if anyone knows.

提交回复
热议问题