使用场景
首先要明白建造者模式是一种创建对象的设计模式。
适用于一个类中有很多属性参数,且当其他地方构建这个类对象的时候又不是所有属性都要用到的时候(这个后面会解释)
抛出问题
来不及解释了,直接上代码。
public class Student {
//姓名
private String mName;
//年龄
private int mAge;
//专业
private String mSubject;
//学历
private String mEducation;
//省份
private String mProvince;
//是否实习过
private Boolean mInternShip;
//是否有女朋友
private Boolean mHaveGirlFriend;
//擅长的语言
private String mLanguage;
}
问题:
现在一个学生要去应聘,所以有一个Student类,里面有八个参数。现在的问题是要创建这个类的实例对象,但是提前是这些属性并不是完全都需要的。比如有些公司只需要提供学生姓名,学校,学历,专业就可以。但是有些公司就会问的很全,甚至可能需要你提供实习信息以及是否有女朋友的情况。所以遇到这种情况该怎么办呢?
第一个解决办法:
1、解决方案
就是通过构建不同的构造函数,比如只要求姓名和年龄就只调用只传姓名和年龄的构造函数。
然后以此类推,要是还需要别的信息,就调用符合条件的构造函数。我下面举几个🌰
//只要求传入名字,年龄
public Student(String name, int age) {
mName = name;
mAge = age;
}
//只要求传入名字,年龄和学科
public Student(String name, int age, String subject) {
mName = name;
mAge = age;
mSubject = subject;
}
//只要求传入擅长语言,学科和是否有女朋友
public Student(String language, String subject, boolean haveGirlFriend) {
mLanguage = language;
mSubject = subject;
mHaveGirlFriend = haveGirlFriend;
}
2、缺点
这里只是列举了几种情况,显而易见,要是想罗列出全部情况,构造函数要写超级多(高中的排列组合我忘记了,谁有兴趣可以算一下写全需要多少构造函数)。而且这样子也不能保证参数的顺序,就是当好几个参数都是一个类型的时候,你很那判断哪个参数对应的是哪个。所以这种情况不可行。
第二个解决办法:
1、解决方法
既然构造函数要写很多是不行的,自然而然会想到set方法,毕竟set方法在这里也就写八个,也是可以接受的。这时候就写一个空的构造函数,然后通过set方法给需要的属性赋值就行。这样就可以通过调用不同属性的set方法从而创建不同的实例对象。代码如下:
Student(){
}
public void setName(String mName) {
this.mName = mName;
}
public void setAge(int mAge) {
this.mAge = mAge;
}
public void setSubject(String mSubject) {
this.mSubject = mSubject;
}
public void setEducation(String mEducation) {
this.mEducation = mEducation;
}
public void setProvince(String mProvince) {
this.mProvince = mProvince;
}
public void setInternShip(Boolean mInternShip) {
this.mInternShip = mInternShip;
}
public void setHaveGirlFriend(Boolean mHaveGirlFriend) {
this.mHaveGirlFriend = mHaveGirlFriend;
}
public void setLanguage(String mLanguage) {
this.mLanguage = mLanguage;
}
2、缺点
虽然这种解决方案相比于第一种构造函数的方式是可行的,但是想想两个情况,因为需要手动调用不同的set方法,所以可能会造成调用错误或者漏调的情况。还有一种情况就是对象会产生不一致的状态,当你想要传入5个参数的时候,你必需将所有的setXX方法调用完成之后才行。然而一部分的调用者看到了这个对象后,以为这个对象已经创建完毕,就直接使用了,其实Student对象并没有创建完成。
第三种解决方法就是使用Builder设计模式,感觉先用文字说明太抽象,所以下面也是直接上代码。
利用Builder设计模式创建对象
具体代码
1、类中构建
public class Student {
//姓名
private String mName;
//年龄
private int mAge;
//专业
private String mSubject;
//学历
private String mEducation;
//省份
private String mProvince;
//是否实习过
private Boolean mInternShip;
//是否有女朋友
private Boolean mHaveGirlFriend;
//擅长的语言
private String mLanguage;
//只要求传入名字,年龄
//私有的无参构造函数
private Student(){
}
public void