建造者模式
建造者模式也是非常常见的一种设计模式,我们经常看到有很多的框架都为我们提供了形如XXXBuilder
的类型,我们一般也是使用这些类来创建我们需要的对象。
比如,我们在JavaSE中就学习过的StringBuiler
类:
public static void main(String[] args) { StringBuilder builder = new StringBuilder(); //创建一个StringBuilder来逐步构建一个字符串 builder.append(666); //拼接一个数字 builder.append("老铁"); //拼接一个字符串 builder.insert(2, '?'); //在第三个位置插入一个字符 System.out.println(builder.toString()); //差不多成形了,最后转换为字符串 }
实际上我们是通过建造者来不断配置参数或是内容,当我们配置完所有内容后,最后再进行对象的构建。
相比直接去new一个新的对象,建造者模式的重心更加关注在如何完成每一步的配置,同时如果一个类的构造方法参数过多,我们通过建造者模式来创建这个对象,会更加优雅。
比如我们现在有一个学生类:
class Student { private int id; private int age; private String name; private String college; private String profession; private List<String> hobby; }
可以看到这个学生类的属性是非常多的,所以构造方法不是一般的长,如果我们现在直接通过new的方式去创建:
public static void main(String[] args) { Student student = new Student(1, 18, "小明", "计算机学院", "学生", Arrays.asList("抽烟", "喝酒","烫头")); }
可以看到,我们光是填参数就麻烦,我们还得一个一个对应着去填,一不小心可能就把参数填到错误的位置了。
所以,我们现在可以使用建造者模式来进行对象的创建:
class Student { private int id; private int age; private String name; private String college; private String profession; private List<String> hobby; // 设置为私有,只给内部类用 private Student(int id, int age, String name, String college, String profession, List<String> hobby) { this.id = id; this.age = age; this.name = name; this.college = college; this.profession = profession; this.hobby = hobby; } /** * 获取建造者 * * @return 建造者 */ public static StudentBuild build() { return new StudentBuild(); } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCollege() { return college; } public void setCollege(String college) { this.college = college; } public String getProfession() { return profession; } public void setProfession(String profession) { this.profession = profession; } public List<String> getHobby() { return hobby; } public void setHobby(List<String> hobby) { this.hobby = hobby; } @Override public String toString() { return "Student{" + "id=" + id + ", age=" + age + ", name='" + name + '\'' + ", college='" + college + '\'' + ", profession='" + profession + '\'' + ", hobby=" + hobby + '}'; } public static class StudentBuild { //Builder也需要将所有的参数都进行暂时保存,所以Student怎么定义的这里就怎么定义 private int id; private int age; private String name; private String college; private String profession; private List<String> hobby; // 这里返回this是为了链式调用 public StudentBuild id(int id) { this.id = id; return this; } public StudentBuild age(int age) { this.age = age; return this; } public StudentBuild name(String name) { this.name = name; return this; } public StudentBuild college(String college) { this.college = college; return this; } public StudentBuild profession(String profession) { this.profession = profession; return this; } public StudentBuild profession(String... hobby) { this.hobby = Arrays.asList(hobby); return this; } public Student build() { return new Student(id, age, name, college, profession, hobby); } } }
现在,我们就可以使用建造者来为我们生成对象了:
public static void main(String[] args) { Student student = Student.build() .id(1) .age(23) .name("张三") .college("信息工程学院") .profession("学生") .profession("抽烟", "喝酒", "烫头") .build(); //Student{id=1, age=23, name='张三', college='信息工程学院', profession='学生', hobby=[抽烟, 喝酒, 烫头]} System.out.println(student); }