1、看下上节的代码:
fun main(args: Array<String>) {
val p=person {
name = "张三"
age = 10
address {
city = "北京市"
street = "北三环街道"
number = 100000
}
}
//这儿可以对name单独修改,如果我们不想这么做呢?
p.name="李四"
}
/**
* 定义address方法
*/
fun Person.address(block:Address.()->Unit)
{
this.address=Address().apply(block)
}
/**
* 首先定义一个方法person,这个返回定义好的Person对象
*/
fun person(block:Person.()->Unit):Person
{
return Person().apply(block)
}
/**
* 我们直接定义成data类型,便于打印
* 城市、街道、街道号
*/
data class Address(var city:String?=null,var street:String?=null,var number:Int?=null)
/**
* 姓名、年龄、地址
*/
data class Person(var name:String?=null,var age:Int?=null,var address: Address?=null)
问题:
//这儿可以对name单独修改,如果我们不想这么做呢?
p.name="李四"
2、构建者模式介绍
看下android中的一段代码,就使用了构建者模式,什么意思呢?
new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setTicker("您有新短消息,请注意查收!")
.setContentTitle("Title")
.setContentText("message")
.build();
我们自己实现下类似的代码:
public class Notifycation {
private String title;
private String content;
private String time;
private Notifycation(Build build)
{
this.title=build.title;
this.content=build.content;
this.time=build.time;
}
static class Build
{
String title;
String content;
String time;
public Build setTitle(String title)
{
this.title=title;
return this;
}
public Build setContent(String content)
{
this.content=content;
return this;
}
public Build setTime(String time)
{
this.time=time;
return this;
}
public Notifycation build()
{
return new Notifycation(this);
}
}
}
现在我们也可以这样写了:
public static void main(String[] args) {
new Notifycation.Build()
.setTitle("标题")
.setContent("内容")
.setTime("时间")
.build();
}
所以构建器模式思想就是先通过一个三方类保存需要的变量 最终拿到所有的变量字段之后 再创建需要的对象Notification
3、我们利用构建者模式解决最开始提出的问题
fun main(args: Array<String>) {
val p=person {
name = "张三"
age = 10
address {
city = "北京市"
street = "北三环街道"
number = 100000
}
}
//这个代码编译期会报错
// p.name=""
println(p)
}
/**
* 定义address方法
*/
fun PersonBuilder.address(block:Address.()->Unit)
{
var address=Address()
block.invoke(address)
this.address=address
}
/**
* 首先定义一个方法person,这个返回定义好的Person对象
*/
fun person(block:PersonBuilder.()->Unit):Person
{
var personBuilder=PersonBuilder()
block.invoke(personBuilder)
return Person(personBuilder.name,personBuilder.age,personBuilder.address)
}
/**
* 我们直接定义成data类型,便于打印
* 城市、街道、街道号
*/
data class Address(var city:String?=null,var street:String?=null,var number:Int?=null)
/**
* 姓名、年龄、地址
*/
data class Person(val name:String?,val age:Int?,val address: Address?)
data class PersonBuilder(var name:String?=null,var age:Int?=null,var address: Address?=null)
输出:
image.png
4、同理,可以对Address也运用构建者模式
fun main(args: Array<String>) {
val p=person {
name = "张三"
age = 10
address {
city = "北京市"
street = "北三环街道"
number = 100000
}
}
//这个代码编译期会报错
// p.name=""
println(p)
}
/**
* 定义address方法
*/
fun PersonBuilder.address(block:AddressBuilder.()->Unit)
{
var addressBuilder=AddressBuilder()
block.invoke(addressBuilder)
this.address=Address(addressBuilder.city,addressBuilder.street,addressBuilder.number)
}
/**
* 首先定义一个方法person,这个返回定义好的Person对象
*/
fun person(block:PersonBuilder.()->Unit):Person
{
var personBuilder=PersonBuilder()
block.invoke(personBuilder)
return Person(personBuilder.name,personBuilder.age,personBuilder.address)
}
/**
* 我们直接定义成data类型,便于打印
* 城市、街道、街道号
*/
data class Address(val city:String?,val street:String?,val number:Int?)
data class AddressBuilder(var city:String?=null,var street:String?=null,var number:Int?=null)
/**
* 姓名、年龄、地址
*/
data class Person(val name:String?,val age:Int?,val address: Address?)
data class PersonBuilder(var name:String?=null,var age:Int?=null,var address: Address?=null)
输出:
image.png