Kotlin:再也不用Build构造方式了

2021-09-29 15:01:16 浏览数 (1)

Builder模式,也是很经典的模式了,在圣经Effective Java中也有提到,当构造参数很多的时候,推荐使用builder模式

Item 2: Consider a builder when faced with many constructor parameters

比如日常开发中,大家估计都使用过的AlertDailog的Builder模式

Builder模式用起来很爽,但是写起来很麻烦,代码量很大,很多都是重复工作的代码,用一个简单的demo说明

定义一个Robot的类,有四个属性

代码语言:javascript复制
class Robot private constructor(
    val code: String,
    val battery: String?,
    val height: Int?,
    val weight: Int?
) {
    class Builder(val code: String) {
        private var battery: String? = null
        private var height: Int? = null
        private var weight: Int? = null

        fun setBattery(battery: String?): Builder {
            this.battery = battery
            return this
        }

        fun setHeight(height: Int?): Builder {
            this.height = height
            return this
        }

        fun setWeight(weight: Int?): Builder {
            this.weight = weight
            return this
        }

        fun build(): Robot {
            return Robot(code, battery, height, weight)
        }
    }
}

在使用的时候,就可以这样调用

代码语言:javascript复制
val robot = Robot.Builder("008")
            .setBattery("r7")
            .setHeight(78)
            .setWeight(23)
            .build()

Builder的设计思路是这样的

  • Robot类内部定义了一个嵌套类Builder,由它负责创建Robot对象
  • Robot类的构造函数用private进行修饰,这样可以确保使用者无法直接通过Robot声明实例
  • 通过在Builder类中定义set方法来对可选的属性进行设置
  • 最终调用Builder类中的build方法来返回一个Robot对象

设计是很优雅,但是书写的工作量大很多,作为码农,为了节省时间来摸鱼,于是有了Koltin的具名的可选参数功能 我们来重新设计上面的Robot

代码语言:javascript复制
class Robot(
    val code: String,
    val battery: String? = null,
    val height: Int? = null,
    val weight: Int? = null
)

就是一个很简单的class类,除了code外,其他参数赋值null,要实例化这个类,可以这样

代码语言:javascript复制
val robot1 = Robot(code = "009")
val robot2 = Robot(code = "006", battery = "u8")
val robot3 = Robot(code = "007", height = 23, weight = 34)

可以发现,相比Builder模式,简单方便了许多

  • 代码十分简单,声明也非常简洁
  • 声明对象时,每个参数名都可以是显式的,并且无须按照顺序书写,非常方便灵活
  • 由于Robot类的每个对象都是val声明的,相较构建者模式者中用var的方案更加安全,在多线程并发安全的业务场景中会显得更有优势

总之,还是Kotlin香

0 人点赞