今天我们聊一下设计模式中的Builder模式(因为感觉在OkHttp里看到了好多它的身影,还有其他大厂的开源库里)。
Builder模式可能你感觉已经遇到了很多,其实可能你遇到的大多数都为精简版或者Builder的变种模式。那么接下来首先先看下标准的Builder的模式
定义:将一个复杂对象的构建及表示进行分离,使得同样的构建过程可以构建不同的表示
使用的场景:
- 相同方法不同的执行顺序并产生不同的事件结果。
- 对象由很多小部件组成,其中的部分部件可以随机搭配构建成对象,导致的结果也不同。
- 当创建一个对象时要传很多参数,并且参数都具有默认值。
- 对象非常复杂,很一部分都会影响其构建结果。
模式中包含的角色:
Product:产品类。
BaseBuilder:为具体Builder的抽象,规定产品的组建并且一般由子类来实现流程。
ConcreteBuilder:具体的Builder类。
Assemble:同一组装类
这样说起来可能比较生硬,下面已简单代码来了解下。比如我们要造一款车,但是我们以后的目标是造各种样式的车
产品类
abstract class Car {
// 车的颜色
var color: String? = null
// 车的类型:suv、轿车、跑车、mpv...
var carType: String? = null
// 尺寸
var size: String? = null
// 要造的车品牌
protected var brand: String? = null
// 设置品牌
internal abstract fun setBrand()
发动机、油耗...
}
具体要造的车
class HavalH100 : Car() {
override fun setType(): String {
return "haval-100"
}
}
抽象Builder类
abstract class BaseBuilder {
abstract fun setColor(color: String)
abstract fun setSize(size: String)
abstract fun carType(carType: String)
abstract fun setBrand()
abstract fun build():Car
}
具体Builder类
class ConcreteBuilder : BaseBuilder() {
private val car: Car = Haval100()
override fun setColor(color: String) {
car.color = color
}
override fun setSize(size: String) {
car.size = size
}
override fun carType(carType: String) {
car.carType = carType
}
override fun setBrand() {
car.setBrand()
}
override fun build(): Car {
return car
}
统一组装类
class Assemble(_builder: BaseBuilder) {
var builder: BaseBuilder = _builder
fun assembling(color: String, size: String, carType: String) {
builder.setColor(color)
builder.setSize(size)
builder.carType(carType)
}
}
进行测试
object Test {
@JvmStatic
fun main(args: Array<String>) {
val builder = ConcreteBuilder()
val assemble = Assemble(builder)
assemble.assembling("红色", "720*1280", "suv")
System.out.print(builder.build().toString())
}
}
输出:
color==红色
carType==suv
size==720*1280
brand==haval-100
Process finished with exit code 0
其实我们遇到的builder模式是非常多的如AlertDialog、OkHttp、Retrofit等等,只是应用中个字框架基本都对Builder模式进行了精简处理,使其架构更加优美。大多数都是直接在组装类中持有内部类Builder,如OkHttpClient、Retrofit等等(代码有点多这里就不贴出来了),Assemble装配类直接被省略掉,使用了Builder模式的精髓而未受其束缚。
顺便提一下,kotlin中也有可用函数类于精简的builder模式供我们直接使用了,很贴心
Car().apply {
this.carType="suv"
this.color="红色"
}
Car().also {
it.carType="suv"
it.color="红色"
}