java设计模式之Builder建造者模式
当遇到多个构造器参数时,考虑用构造器模式。里面有个商品的例子。这让我想到了熟悉的学生信息管理系统。
拿研究生来说吧,入学考试后先进行面试和体检,然后是录取,最后是入学分班。这几个阶段对学生的信息需求是不一样的。
我们首先基于以下假设:
1、体检时只需要知道我们的姓名、性别、年龄和身高等信息。
2、录取的时候,需要在体检基本信息的基础上添加院系、年级等信息。
3、入学分班后,需要添加班号(班级编号)等信息。
4、正式开学后,为了便于管理,又需要完善身份证、学号、实验室名称和宿舍地址等信息。
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;
//要求分班的时候,名字相同的同学不能分配到一个班级
private int gradeNo;//年级编号
//扩展信息
private String idCard;//身份证号
private String stuNo;//学号
private String labName;//实验室名称
private String dormitoryAddress;//宿舍地址
/**
* 创建一个基本学生信息 ,例如在研究生入学体检时,不需要专业、年级信息,
* 因此,可以只适用必须的参数创建一个基本信息
* @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;
}
/**
* 创建一个基本学生信息 ,研究生正式录取后,学校的学生信息管理系统需要学生基本信息
* @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;
}
/**
* 开学了,为了教学方便,学校进行了分班,同时要求在创建分班的时候,
* 要求名字相同不分到同一个班级
* @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("不合法的学生信息,同名的学生不能分到同一个班级...");
}
/**
* 学生信息合法性校验
* @return
*/
public boolean isValidStudent(){
boolean flag = true;
//TODO 进行用户信息合法性校验
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;
}
}
当其中的构造参数的数量越来越多,构造参数使用起来就不是很方便了,这个时候使用get和set也不大方便
所以可以采用Builder设计模式来进行改造
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;
//要求分班的时候,名字相同的同学不能分配到一个班级
private final int gradeNo;//年级编号
//扩展信息
private final String idCard;//身份证号
private final String stuNo;//学号
private final String labName;//实验室名称
private final String dormitoryAddress;//宿舍地址
/**
* 创建一个基本学生信息 ,例如在研究生入学体检时,不需要专业、年级信息,
* 因此,可以只适用必须的参数创建一个基本信息
* @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;
//要求分班的时候,名字相同的同学不能分配到一个班级
private int gradeNo=0;//年级编号
//扩展信息
private String idCard;//身份证号
private String stuNo;//学号
private String labName;//实验室名称
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;
}
// 构造器入口
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 + "]";
}
}
网友评论