java設(shè)計(jì)模式之Builder建造者模式
當(dāng)遇到多個(gè)構(gòu)造器參數(shù)時(shí),考慮用構(gòu)造器模式。里面有個(gè)商品的例子。這讓我想到了熟悉的學(xué)生信息管理系統(tǒng)。
拿研究生來(lái)說(shuō)吧,入學(xué)考試后先進(jìn)行面試和體檢,然后是錄取,最后是入學(xué)分班。這幾個(gè)階段對(duì)學(xué)生的信息需求是不一樣的。
我們首先基于以下假設(shè):
1、體檢時(shí)只需要知道我們的姓名、性別、年齡和身高等信息。
2、錄取的時(shí)候,需要在體檢基本信息的基礎(chǔ)上添加院系、年級(jí)等信息。
3、入學(xué)分班后,需要添加班號(hào)(班級(jí)編號(hào))等信息。
4、正式開學(xué)后,為了便于管理,又需要完善身份證、學(xué)號(hào)、實(shí)驗(yàn)室名稱和宿舍地址等信息。
package com.icecode.data;
public class Student {
private String name;
private int age;
private int height;
private int sex; //0表示男性,1表示女性,其它值非法
private String schoolName;
private String profession;
//要求分班的時(shí)候,名字相同的同學(xué)不能分配到一個(gè)班級(jí)
private int gradeNo;//年級(jí)編號(hào)
//擴(kuò)展信息
private String idCard;//身份證號(hào)
private String stuNo;//學(xué)號(hào)
private String labName;//實(shí)驗(yàn)室名稱
private String dormitoryAddress;//宿舍地址
/**
* 創(chuàng)建一個(gè)基本學(xué)生信息 ,例如在研究生入學(xué)體檢時(shí),不需要專業(yè)、年級(jí)信息,
* 因此,可以只適用必須的參數(shù)創(chuàng)建一個(gè)基本信息
* @param name
* @param age
* @param height
* @param sex
*/
public Student(String name, int age, int height, int sex) {
super();
this.name = name;
this.age = age;
this.height = height;
this.sex = sex;
}
/**
* 創(chuàng)建一個(gè)基本學(xué)生信息 ,研究生正式錄取后,學(xué)校的學(xué)生信息管理系統(tǒng)需要學(xué)生基本信息
* @param name
* @param age
* @param height
* @param sex
* @param schoolName
* @param profession
*/
public Student(String name, int age, int height, int sex,
String schoolName, String profession) {
super();
this.name = name;
this.age = age;
this.height = height;
this.sex = sex;
this.schoolName = schoolName;
this.profession = profession;
}
/**
* 開學(xué)了,為了教學(xué)方便,學(xué)校進(jìn)行了分班,同時(shí)要求在創(chuàng)建分班的時(shí)候,
* 要求名字相同不分到同一個(gè)班級(jí)
* @param name
* @param age
* @param height
* @param sex
* @param schoolName
* @param profession
* @param gradeNo
* @throws Exception
*/
public Student(String name, int age, int height, int sex,
String schoolName, String profession, int gradeNo) throws Exception {
super();
this.name = name;
this.age = age;
this.height = height;
this.sex = sex;
this.schoolName = schoolName;
this.profession = profession;
this.gradeNo = gradeNo;
if(isValidStudent() == false)
throw new Exception("不合法的學(xué)生信息,同名的學(xué)生不能分到同一個(gè)班級(jí)...");
}
/**
* 學(xué)生信息合法性校驗(yàn)
* @return
*/
public boolean isValidStudent(){
boolean flag = true;
//TODO 進(jìn)行用戶信息合法性校驗(yàn)
return flag;
}
public Student(String name, int age, int height, int sex,
String schoolName, String profession, int gradeNo, String idCard,
String stuNo, String labName, String dormitoryAddress) {
super();
this.name = name;
this.age = age;
this.height = height;
this.sex = sex;
this.schoolName = schoolName;
this.profession = profession;
this.gradeNo = gradeNo;
this.idCard = idCard;
this.stuNo = stuNo;
this.labName = labName;
this.dormitoryAddress = dormitoryAddress;
}
}
當(dāng)其中的構(gòu)造參數(shù)的數(shù)量越來(lái)越多,構(gòu)造參數(shù)使用起來(lái)就不是很方便了,這個(gè)時(shí)候使用get和set也不大方便
所以可以采用Builder設(shè)計(jì)模式來(lái)進(jìn)行改造
package com.ipaynow.effective.bean;
public class StudentB {
private final String name;
private final int age;
private final int height;
private final int sex; //0表示男性,1表示女性,其它值非法
private final String schoolName;
private final String profession;
//要求分班的時(shí)候,名字相同的同學(xué)不能分配到一個(gè)班級(jí)
private final int gradeNo;//年級(jí)編號(hào)
//擴(kuò)展信息
private final String idCard;//身份證號(hào)
private final String stuNo;//學(xué)號(hào)
private final String labName;//實(shí)驗(yàn)室名稱
private final String dormitoryAddress;//宿舍地址
/**
* 創(chuàng)建一個(gè)基本學(xué)生信息 ,例如在研究生入學(xué)體檢時(shí),不需要專業(yè)、年級(jí)信息,
* 因此,可以只適用必須的參數(shù)創(chuàng)建一個(gè)基本信息
* @param name
* @param age
* @param height
* @param sex
*/
public StudentB(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.height = builder.height;
this.sex = builder.sex;
this.schoolName = builder.schoolName;
this.profession = builder.profession;
this.gradeNo = builder.gradeNo;
this.idCard = builder.idCard;
this.stuNo = builder.stuNo;
this.labName = builder.labName;
this.dormitoryAddress = builder.dormitoryAddress;
}
public static class Builder{
private final String name;
private final int age;
private final int height;
private final int sex; //0表示男性,1表示女性,其它值非法
private String schoolName ;
private String profession;
//要求分班的時(shí)候,名字相同的同學(xué)不能分配到一個(gè)班級(jí)
private int gradeNo=0;//年級(jí)編號(hào)
//擴(kuò)展信息
private String idCard;//身份證號(hào)
private String stuNo;//學(xué)號(hào)
private String labName;//實(shí)驗(yàn)室名稱
private String dormitoryAddress;//宿舍地址
public Builder(String name, int age, int height, int sex) {
this.name = name;
this.age = age;
this.height = height;
this.sex = sex;
}
public Builder sprofession(String val){
profession=val;
return this;
}
public Builder gradeNo(int val){
this.gradeNo=val;
return this;
}
public Builder schoolName(String val){
this.schoolName=val;
return this;
}
public Builder setIdCard(String val) {
this.idCard = val;
return this;
}
public Builder setStuNo(String val) {
this.stuNo = val;
return this;
}
public Builder labName(String labName) {
this.labName = labName;
return this;
}
public Builder dormitoryAddress(String val) {
this.dormitoryAddress = val;
return this;
}
// 構(gòu)造器入口
public StudentB build(){
return new StudentB(this);
}
}
@Override
public String toString() {
return "StudentB [name=" + name + ", age=" + age + ", height=" + height + ", sex=" + sex + ", schoolName="
+ schoolName + ", profession=" + profession + ", gradeNo=" + gradeNo + ", idCard=" + idCard + ", stuNo="
+ stuNo + ", labName=" + labName + ", dormitoryAddress=" + dormitoryAddress + "]";
}
}