【Java】基于方法引用的构建器模式运用

思考

封装一个 set 对象构建器,利用类的 set 引用方法(不局限 set 开头的方法)来设值,便于点式调用。

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

import cn.hutool.core.bean.BeanUtil;
import lombok.Data;

@Data
public class User {
private String name;
private Integer age;
private String sex;
private String email;

private String other;

public void appendOther(String other) {
this.other = other;
}

public static void main(String[] args) {
// 方法1,普通语法(推荐)
User user1 = new User();
user1.setName("Jojo");
user1.setAge(18);
user1.setSex("女");
user1.setEmail("JoJo@example.com");
user1.appendOther("其他数据");
System.out.println(user1);

// 方法2,双括号语法(本质是匿名函数。不推荐使用,可能引起内层泄露)
User user2 = new User() {{
setName("Jojo");
setAge(18);
setSex("女");
setEmail("JoJo@example.com");
appendOther("其他数据");
}};
System.out.println(user2);

// 方法3:set 构建器(推荐)
final User user3 = SetBuilder.of(new User())
.set(User::setName, "JoJo")
.set(User::setAge, 18)
.set(User::setSex, "女")
.set(User::setEmail, "JoJo@example.com")
.set(User::appendOther, "其他数据")
.build();
System.out.println(user3);

// 方法4:反射设值
final User user4 = new User();
BeanUtil.setFieldValue(user4, "name", "JoJo");
BeanUtil.setFieldValue(user4, "age", 18);
BeanUtil.setFieldValue(user4, "sex", "女");
BeanUtil.setFieldValue(user4, "email", "JoJo@example.com");
BeanUtil.setFieldValue(user4, "other", "其他数据");
System.out.println(user4);
}
/**
* 打印:
User(name=Jojo, age=18, sex=女, email=JoJo@example.com, other=其他数据)
User(name=Jojo, age=18, sex=女, email=JoJo@example.com, other=其他数据)
User(name=JoJo, age=18, sex=女, email=JoJo@example.com, other=其他数据)
User(name=JoJo, age=18, sex=女, email=JoJo@example.com, other=其他数据)
*/
}

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/**
* 封装一个set构建器,基于对象的 set 引用方法来设值
* <p>
* @param <T> 指定对象泛型
*/
public class SetBuilder<T> {
private final T object;

public static <T> SetBuilder<T> of(T object) {
return new SetBuilder<>(object);
}

/**
* 构造函数
*
* @param object 对象
*/
public SetBuilder(T object) {
this.object = object;
}

/**
* 链式调用
*
* @param setter set引用方法
* @param value 要设置的属性值
* @param <V> 对象泛型
* @return builder,可链式调用
*/
public <V> SetBuilder<T> set(Setter<T, V> setter, V value) {
setter.set(object, value);
return this;
}


/**
* 构建
*
* @return 构建后对象
*/
public T build() {
return object;
}

@FunctionalInterface
public interface Setter<T, V> {

/**
* 调用set方法
*
* @param t 实体对象
* @param value 实体对象属性值
*/
void set(T t, V value);
}

}