博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Kotlin 更加优雅的 Builder - 理解 with
阅读量:5777 次
发布时间:2019-06-18

本文共 2546 字,大约阅读时间需要 8 分钟。

引言

在 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 fun 
with(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。

转载地址:http://tsuyx.baihongyu.com/

你可能感兴趣的文章
Docker容器从一知半解到入门
查看>>
关于“方法参数”
查看>>
Redis命令总结
查看>>
unable to write 'random state'错误解决
查看>>
context:annotation-config vs component-scan
查看>>
结构体和类的内存对齐原则-这一次弄清楚了对齐的本质规则
查看>>
Centos编译安装Nginx和PHP
查看>>
Linux-grep命令
查看>>
exgcd、二元一次不定方程学习笔记
查看>>
经典sql
查看>>
CSS3边框会动的信封
查看>>
JavaWeb实例设计思路(订单管理系统)
查看>>
source insight中的快捷键总结
查看>>
PC-IIS因为端口问题报错的解决方法
查看>>
java四种线程池简介,使用
查看>>
一般处理程序(.ashx)中session的使用方法
查看>>
EasyUI笔记(二)Layout布局
查看>>
ios View之间的切换 屏幕旋转
查看>>
typedef BOOL(WINAPI *MYFUNC) (HWND,COLORREF,BYTE,DWORD);语句的理解
查看>>
jsp 特殊标签
查看>>