前言
在设计模式的分类中,建造者模式属于创建型模式,建造者模式主要由两种应用场景。
第一种应用场景
首先,适用于一些复杂对象的构建。就拿造房子来说,一个房子要建造起来,就要确定房子的长、宽、高、预算等,这些参数也取决于我是要建造一个大房子还是小房子,正常的方法可能就是new一个,通过构造器赋值,或者通过setter赋值。用建造者模式则是这样的
House:
//省略了set,get等
public class House {
private Integer height;
private Integer width;
private Integer length;
private Integer price;
}
Builder:
public interface Builder {
void buildLength();
void buildWidth();
void buildHeight();
void buildPrice();
House getHouse();
}
如果说要建一所大房子,那么就需要一个类去继承Builder接口,完成里面一些参数的赋值
public class BigHouseBuilder implements Builder {
private House house = new House();
@Override
public void buildLength() {
house.setLength(100);
}
@Override
public void buildWidth() {
house.setWidth(100);
}
@Override
public void buildHeight() {
house.setHeight(100);
}
@Override
public void buildPrice() {
house.setPrice(1000000);
}
@Override
public House getHouse() {
return house;
}
}
建造前的准备工作做好了,那不是需要建筑工人们施工去完成建造吗?
public class Workers {
private Builder builder;
public Workers(Builder builder) {
this.builder = builder;
}
public House build() {
builder.buildHeight();
builder.buildLength();
builder.buildWidth();
builder.buildPrice();
return builder.getHouse();
}
}
测试类:
public class mainTest {
public static void main(String[] args) {
BigHouseBuilder builder = new BigHouseBuilder();
Workers workers = new Workers(builder);
House house = workers.build();
System.out.println(house.toString());
}
}
这时候主程序代码就很直观,很简洁。
同属于创建型模式,建造者模式和抽象工厂模式还是很像的,不过两者还是有一定区别,抽象工厂模式中往往一个函数就可以创建一个对象,而建造者模式则是创建单个对象。
第二种场景
对于第二种场景,网上一些比较浅的文章中没有提到。设计模式这东西学了一段时间,其实看看还是很简单的,但重要的还是一个实践的过程(好像整个计算机相关的知识都是这样,看看理论知识不难,代码实现起来就不是这么一回事了,所以自己也写例子,写博文,希望能早日参透)。回过神来,来讲讲第二种场景,主要用于javabean中,如果说一个javabean中有很多的属性,而且不是所有的属性都是必须的,那么再使用构造器的方式就很容易出错,一旦某两个参数的位置写反了,那么问题就大了。如果使用setter的方法,代码也是十分臃肿,不利于维护。就拿学生信息来举个例子吧,现在我们有学生的一些基本信息(姓名,学号之类),以及他某一学期的成绩,如果说要把这些信息存入同一个对象中,代码应该是这样的:
Base(成绩)(省略了get和set)
public class Base {
private Integer chinese;
private Integer maths;
private Integer english;
}
基本信息Student
public class Student {
private String name;
private String id;
}
目标类StudentInfo
public class StudentInfo {
private String name;
private String id;
private Integer chinese;
private Integer maths;
private Integer english;
public static class Builder {
private String name;
private String id;
private Integer chinese;
private Integer maths;
private Integer english;
public Builder base(Base base) {
this.chinese = base.getChinese();
this.english = base.getEnglish();
this.maths = base.getMaths();
return this;
}
public Builder student(Student student) {
this.id = student.getId();
this.name = student.getName();
return this;
}
public StudentInfo build() {
StringBuffer stringBuffer = new StringBuffer();
return new StudentInfo(this);
}
}
private StudentInfo(Builder builder) {
this.name = builder.name;
this.chinese = builder.chinese;
this.english = builder.english;
this.maths = builder.maths;
this.id = builder.id;
this.name = builder.name;
}
}
目标类中还是需要注意的,对StudentInfo类的构造函数进行了私有化,通过内部静态类Builder的build()去调用构造函数。
测试类:
public static void main(String[] args) {
Student student = new Student("dmc", "1001");
Base base = new Base(50, 150, 100);
StudentInfo studentInfo = new StudentInfo.Builder()
.student(student)
.base(base)
.build();
System.out.println(studentInfo.toString());
}