文章目录
本文主要用于介绍构造函数的使用及优点。
思考:现在需要创建一个学生类(Student)的实体对象,其中学号(id)和姓名(name)为必填字段,其他字段为选填字段,要如何构建呢?。
一、构造函数
面对前言中的思考问题,首先应该能想到的是通过构造函数来实现,可通过穷举的方式创建多个构造函数以便于不同场景下的使用。
1.示例
例如:学生类(Student)除了必填的学号(id)和姓名(name)字段还有其他三个字段A,B,C那么则需要创建8种构造函数供不同场景的使用:
1.id+name
2.id+name+A
3.id+name+B
4.id+name+C
5.id+name+A+B
6.id+name+A+C
7.id+name+B+C
8.id+name+A+B+C
2.缺点
可以看出根据排列组合,如果选填字段较多,则会生成大量的构造函数。而且如果要新增或删除某个字段,受到影响的构造函数会有很多,字段和多个构造函数耦合在了一起,这显然不符合低耦合,可拓展性的要求。
二、Set方法
当发现构造函数无法实现需求时,第一想法是用set方法来实现。只保留一个拥有全部必填字段的构造函数,其他字段通过set方法射入。
1.实现方式
只保留一个拥有全部必填字段的构造函数,其他字段通过set方法射入。这种方式避免了大量构造函数的创建,因此扩展和删除字段也不会太过麻烦,事实上大部分的bean对象都是如此的。
2.缺点
若是我们要创建的是一个不可变类,或其中存在不可变字段,如:我们认为学生类(Student)的出生年份字段(birthYear)一但初始化了,就不应该会改变了。set方法显然破坏了其封装性。
三、构造器模式
综上,这里推荐使用构造器模式,通过静态内部类的形式创建一个构造器(Builder),构造器和类(Student)拥有相同的字段,为构造器创建包含所有必填字段的构造函数,再为构造器的其他字段设置set注入方法,最后为类创建构造函数参数是构造器Builder。
1.代码示例
代码如下(示例):
@ToString
public class Student {
private String id; //必填
private String name; //必填
private String birthYear; //选填
private Double height; //选填
private Double weight; //选填
public Student(Builder builder) {
this.id = builder.id;
this.name = builder.name;
this.birthYear = builder.birthYear;
this.height = builder.height;
this.weight =builder.weight;
}
public static class Builder{
private String id;
private String name;
private String birthYear;
private Double height;
private Double weight;
public Builder(String id, String name) {
this.id = id;
this.name = name;
}
public Builder birthYear(String birthYear) {
this.birthYear = birthYear;
return this;
}
public Builder height(Double height) {
this.height = height;
return this;
}
public Builder weight(Double weight) {
this.weight = weight;
return this;
}
public Student build(){
return new Student(this);
}
}
}
2.构造演示
代码如下(示例):
public class Test {
public static void main(String[] args) {
Student student = new Student.Builder("1527","Rukia").birthYear("1996").build();
System.out.println(student);
}
}
运行结果如下(示例):
Student(id=1527, name=Rukia, birthYear=1996, height=null, weight=null)
总结
综上,构造器模式降低了代码的耦合性,凸显了封装的特性,在某些情况下可以参考着使用。