Builder 模式非常灵活。 单个 builder 可以重复使用来构建多个对象。 builder 的参数可以在构建方法的调用之间进行调整,以改变创建的对象。 builder 可以在创建对象时自动填充一些属性,例如每次创建对象时增加的序列号。
Builder 模式也有缺点。为了创建对象,首先必须创建它的 builder。虽然创建这个 builder 的成本在实践中不太可能被注意到,但在看中性能的场合下这可能就是一个问题。而且,builder 模式比伸缩构造方法模式更冗长,因此只有在有足够的参数时才值得使用它,比如四个或更多。但是请记住,你可能在以后会想要添加更多的参数。但是,如果你一开始是使用的构造方法或静态工厂,当类演化到参数数量失控的时候再转到Builder模式,过时的构造方法或静态工厂就会面临尴尬的处境。因此,通常最好从一开始就创建一个 builder。
单个Builder设计模式
public class NutritionFacts {
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
private final int sodium;
private final int carbohydrate;
public static class Builder {
// Required parameters
private final int servingSize;
private final int servings;
// Optional parameters - initialized to default values
private int calories = 0;
private int fat = 0;
private int sodium = 0;
private int carbohydrate = 0;
public Builder(int servingSize, int servings) {
this.servingSize = servingSize;
this.servings = servings;
}
public Builder calories(int val)
{ calories = val; return this; }
public Builder fat(int val)
{ fat = val; return this; }
public Builder sodium(int val)
{ sodium = val; return this; }
public Builder carbohydrate(int val)
{ carbohydrate = val; return this; }
public NutritionFacts build() {
return new NutritionFacts(this);
}
}
/**
* 构造方法添加Builder
* @param builder
*/
private NutritionFacts(Builder builder) {
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
sodium = builder.sodium;
carbohydrate = builder.carbohydrate;
}
public static void main(String[] args) {
NutritionFacts cocaCola = new Builder(240, 8)
.calories(100).sodium(35).carbohydrate(27).build();
System.out.println(" cocaCola = "+ cocaCola.calories);
}
}
单个Builder模式不利于扩展,下面是升级版Builder模式
//person抽象类
public abstract class Person {
//name age 专门的属性
final String name;
final Integer age;
//构造方法 参数静态内部类
Person(PersonBuild personBuild){
//通过静态内部类属性 赋值给 Person name age 参数
this.name = personBuild.name;
this.age = personBuild.age;
}
//抽象静态内部类(一定要静态类,通过实例化内部类PersonBuild的build方法 返回外部类)
abstract static class PersonBuild<T extends PersonBuild,R extends Person> {
String name;
Integer age;
//对属性进行赋值 返回T (静态内部类本身)
protected T name(String name){
this.name = name;
return self();
}
protected T age(Integer age){
this.age = age;
return self();
}
//外部类person 通过 PersonBuild build方法 实例化 返回
abstract R build();
//self 返回本身,子类对应 this
abstract T self();
}
}
//子类继承抽象类person
public class Student extends Person{
//增加学生专业属性值
final Integer studentNo;
Student(StudentBuilder personBuild) {
super(personBuild);
this.studentNo = personBuild.studentNo;
}
//继承父类 静态抽象内部类
static class StudentBuilder extends PersonBuild<StudentBuilder,Student>{
Integer studentNo;
public StudentBuilder addStudentNo(Integer studentNo){
this.studentNo = studentNo;
return this;
}
//通过build()方法 实例化外部类Student 并返回
@Override
Student build() {
return new Student(this);
}
//返回this
@Override
StudentBuilder self() {
return this;
}
}
@Override
public String toString() {
String studentStr = String.format("{ studentNo = %d, age = %d ,name = %s }",studentNo,age,name);
return studentStr;
}
}
//main函数
public class PersonMain {
public static void main(String[] args) {
Student student = new Student.StudentBuilder().addStudentNo(122332434).age(1222).name("1223").build();
System.out.println(" student = "+student);
}
}