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香