我们常常能碰到一个对象有非常多属性的时候,比如一个雇员信息,包括姓名,年龄,性别,住址,级别,身高,体重,身份证号,社保福利,绩效...等等字段,有时候我们需要得到部分字段的信息,也有可能需要获取全部字段信息,如果一个字段一个字段的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 + '\'' +
'}';
}
}
我在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);
}
需要构造什么字段,直接在new Employee.EmployeeBuilder()
后面.
什么方法就行了,这是经典的链式编程的方式,每个方法返回对象本身就可以实现。
本例中代码实现就使用了builder的设计模式,通过builder模式我们很容易就能构造像Employee这样很复杂的对象。
builder设计模式就是用来构造复杂对象
的,其特点:
其实,我们在工作中自然而然的就会使用这种模式,我们无须对模式的概念啊,定义啊进行特别的记忆,用的时候自然实用,水到渠成。
比如,
StringBuilder sb = new StringBuilder();
sb.append("下蛋公鸡").append(",").append("公鸡中的战斗鸡!");
System.out.println(sb.toString());
还有StringBuffer
也可以这样用,我们来看一下源码:
StringBuilder
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
//...略
//append()方法返回对象本身,这样在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;
}
//...
}
StringBuffer
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
//...
//方法和StringBuilder的append实现方式是一样的(他们都继承了AbstractStringBuilder类),只不过方法加了synchronized关键字,是线程安全的。
@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;
}
//...
}
他们的父类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;
}
//...
}
StringBuilder&StringBuffer
这也是建造者模式的体现。
大名鼎鼎的Mybatis的SqlSessionFactoryBuilder
就使用了builder模式
:
MyBatis的SqlSessionFactoryBuilder
这一堆的build方法返回都是SqlSessionFactory,调用不同的方法,可以构建出不同特性的SqlSessionFactory。
无需记忆,自然使用。
看完点赞,养成习惯。举手之劳,赞有余香。