引言
在 Android 开发过程中,我们经常需要对一个组件进行多个参数的自定义,但是如果单纯使用构造函数来实现是非常麻烦的:
public class Component { public Component(int id) { } public Component(String name) { } public Component(int id, String name) { }}复制代码
可见,当参数一多,代码量急剧上升,而且调用的时候也很不好看。
有人说,我可以先把对象实例化出来之后在用 setter
设置各个参数啊。是的,那确实是一种很简单的 approach,但是这种结构不够紧凑,我们想要的是一块整体的代码或一句代码就完成实例化。
Builder
设计模式就是来解决这类问题的。
使用 Builder 后,我们在实例化组件的时候,可以像下面这样:
Component c = new Component.Builder() .id(id) .name(name) .build()复制代码
代码结构更加清晰,而且参数的自定义更加灵活。
Java 的窘境
用 Java 写 Builder 有点一言难尽:
public class Component { private Builder mBuilder; private Component(Builder builder) { mBuilder = builder; } public static class Builder { private int id = 0; private String name = "xxx"; public Builder id(int id) { this.id = id; return this; } public Builder name(String name) { this.name = name; return this; } public Component build() { return new Component(this); } }}复制代码
可以看到,虽然对于参数的自定义比直接用构造方法的方式灵活不少,但是我们需要创建静态内部类,而且写很多样板代码,这样开发的效率较低。
Kotlin 的曙光
Kotlin 作为新晋 Android 开发语言,其与 Java 的互操性和灵活性让人赞不绝口,我们看看她在 Builder 设计模式上能给我们带来什么。
首先,需要理解 with
方法:
inline funwith(receiver: T, block: T.() -> R): R {...}复制代码
with
接受两个参数,第一个是 T
类型对象,第二个是该对象内部的一个方法,该方法返回一个 R
类型的对象。
也就是说,with
能调用一个 T
类型对象里面的方法来返回一个 R
类型对象。
比如我们有一个类:
class Paint() { var color = Color.WHITE fun drawPig() { } fun drawDog() { } fun getString(): String { }}复制代码
那么我们可以像这样调用:
val string = with(Paint(), { //看不懂这部分写法的请先了解一哈 kotlin 的 lambda 表达式 color = Color.BLACK drawDog() color = Color.PINK drawPig() getString() //最后一个语句的返回值为整个方法的返回值 })复制代码
相当于,我们创建了一个 Paint
对象,并对调用了该对象的各种方法(或者修改成员变量)。也就是说,直接在 {}
里面营造 Paint
类的环境,使 Paint
对象的方法和成员变量可以直接访问。
上面整块代码相当于:
val paint = Paint()val string = with(paint) { paint.color = Color.BLACK paint.drawDog() paint.color = Color.PINK paint.drawPig() paint.getString() //作为返回值返回}复制代码
在中,我们将使用 with
来打造 Builder
。
———
技术上的问题,欢迎讨论。
最近在 上维护的项目:
- [一款用 Kotlin 编写,基于 MD 风格的轻量天气 App],对使用 Kotlin 进行实际开发感兴趣的同学可以看看,项目中会使用到 Kotlin 的委托机制、扩展机制和各种新奇的玩意。
- [一款基于 MD 的极轻阅读 App,提供知乎日报、豆瓣电影等资源],项目主要使用了 MVVM 设计模式,界面遵循 Material Design 规范,提供轻量的阅读体验。
- [Kotlin 编写的 Android MVVM 框架,基于 android-architecture],轻量 MVVM+Databinding 开发框架。
- [Kotlin 编写的 Android 扩展库]。
欢迎 star/fork/follow 提 issue 和 PR。