用kotlins扩展函数以dsl结构化的方式填充对象

82 阅读1分钟

这里的对象可以看成一棵树,里面的所有属性都需要填充(用的是builder模式),常见的情况是对象里面套对象,像这样:

final ClientBuilder builder = new ClientBuilder();

builder.setFirstName("Anton");
builder.setLastName("Arhipov");

final TwitterBuilder twitterBuilder = new TwitterBuilder();
twitterBuilder.setHandle("@antonarhipov");
builder.setTwitter(twitterBuilder.build());

final CompanyBuilder companyBuilder = new CompanyBuilder();
companyBuilder.setName("JetBrains");
companyBuilder.setCity("Tallinn");
builder.setCompany(companyBuilder.build());

final Client client = builder.build();
System.out.println("Created client is: " + client);

中间要是不加空行,就是密密麻麻的一大堆。 而如果善加利用kotlin,写出来的就是简明清晰如下的:

val c1 = client {
    firstName = "Anton"
    lastName = "Arhipov"
    twitter {
        handle = "@antonarhipov"
    }
    company {
        name = "JetBrains"
        city = "Tallinn"
    }
}
println("Created client is: $c1")

其中的magic就是靠扩展函数:

fun ClientBuilder.company(block: CompanyBuilder.() -> Unit) {
    company = CompanyBuilder().apply(block).build()
}

fun ClientBuilder.twitter(block: TwitterBuilder.() -> Unit) {
    twitter = TwitterBuilder().apply(block).build()
}

fun client(c: ClientBuilder.() -> Unit): Client {
    val builder = ClientBuilder()
    c(builder)
    return builder.build()
}

项目的完整代码在:github.com/antonarhipo… 需要你解开注释