【设计模式】1分钟整明白什么是Builder建造者模式
作者:行百里er
博客:https://chendapeng.cn (opens new window)
提示
这里是 行百里er 的博客:行百里者半九十,凡事善始善终,吾将上下而求索!
# 场景切入
我们常常能碰到一个对象有非常多属性的时候,比如一个雇员信息,包括姓名,年龄,性别,住址,级别,身高,体重,身份证号,社保福利,绩效...等等字段,有时候我们需要得到部分字段的信息,也有可能需要获取全部字段信息,如果一个字段一个字段的set,那是相当繁琐的!!!
# 代码解决
针对如上情况,该怎么简化如此繁琐的工作呢?别急,builder
模式来帮忙!
直接上代码看效果:
public class Employee {
private String name;
private Integer age;
private String sex;
private Integer height;
private Integer weight;
private String address;
private String level;
//...还有很多属性
//私有的构造方法
private Employee(){
}
public static class EmployeeBuilder{
Employee employee = new Employee();
public EmployeeBuilder basicInfo(String name, Integer age, String sex){
employee.name = name;
employee.age = age;
employee.sex = sex;
return this;
}
public EmployeeBuilder height(Integer height){
employee.height = height;
return this;
}
public EmployeeBuilder weight(Integer weight){
employee.weight = weight;
return this;
}
public EmployeeBuilder address(String address){
employee.address = address;
return this;
}
public EmployeeBuilder level(String level){
employee.level = level;
return this;
}
public Employee build(){
return employee;
}
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", height=" + height +
", weight=" + weight +
", address='" + address + '\'' +
", level='" + level + '\'' +
'}';
}
}
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
我在Employee类中定义了一个静态内部类 EmployeeBuilder
,负责将 Employee 类的字段拆分,静态内部类每个方法都负责给相应的字段赋值,最后定义一个 build()
方法来返回我们需要的 Employee 对象。
来看调用:
public static void main(String[] args) {
Employee e = new Employee.EmployeeBuilder()
.basicInfo("张三", 18, "男")
.height(178)
.weight(65)
//.level("初级")
.build();
System.out.println(e);
}
2
3
4
5
6
7
8
9
需要构造什么字段,直接在 new Employee.EmployeeBuilder()
后面 .
什么方法就行了,这是经典的链式编程
的方式,每个方法返回对象本身就可以实现。
# builder模式
本例中代码实现就是用了 builder
的设计模式,通过 builder 模式我们很容易就能构造像 Employee 这样很复杂的对象。
builder设计模式就是用来 构造复杂对象
的,其特点:
- 分离复杂对象的构建和表示
- 同样的构建过程可以创建不同的表示
其实,我们在工作中自然而然的就会使用这种模式,我们无须对模式的概念啊,定义啊进行特别的记忆,用的时候自然实用,水到渠成。
比如,
StringBuilder sb = new StringBuilder();
sb.append("下蛋公鸡").append(",").append("公鸡中的战斗鸡!");
System.out.println(sb.toString());
2
3
还有 StringBuffer
也可以这样用,我们来看一下源码:
StringBuilder :
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
//...略
//append()方法返回对象本身,这样在append一次之后还能接着直接.append()的方式调用。
@Override
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
//...
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
append()
方法返回对象本身,这样在 append 一次之后还能接着直接 .append()
的方式调用。
这其实就是 建造者模式 的体现,可以一部分一部分的建造对象,根据实际需要来调用 append()
方法。
StringBuffer :
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
//...
//方法和StringBuilder的append实现方式是一样的(他们都继承了AbstractStringBuilder类)
@Override
public synchronized StringBuffer append(Object obj) {
toStringCache = null;
super.append(String.valueOf(obj));
return this;
}
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
//...
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
StringBuffer 的 append()
方法和 StringBuilder 的 append()
方法实现方式是一样的——他们都继承了AbstractStringBuilder类,只不过方法加了 synchronized
关键字,是线程安全的。
他们的父类 AbstractStringBuilder :
abstract class AbstractStringBuilder implements Appendable, CharSequence {
//...
public AbstractStringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
//...
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
这也是建造者模式的体现。
Mybatis的 SqlSessionFactoryBuilder
就使用了 builder模式
:
这一堆的 build
方法返回都是 SqlSessionFactory
,调用不同的方法,可以构建出不同特性的 SqlSessionFactory 。
# 小结
- 相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式。
- 产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式非常合适。
- 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,则可以使用该模式。
无需记忆,自然使用。
首发公众号 行百里er ,欢迎老铁们关注阅读指正。