Java Builder模式 初体验
看来Java构造器模式,决定动手体验下。构造器模式是什么?干什么用的?推荐大家看下ITEYE的一篇文章
http://www.iteye.com/topic/71175
了解构造器模式对于系统的重构,也是很有帮助的。例如,可以优化多构造器类的设计。
首先,我先寻找一个应用场景。拿民工和设计师来写固然可以,但觉得有点类似写Hello word的感觉。学习编程语言和设计模式,很多时候只有将学到的东西和实际应用结合起来的时候,才会深入体会,获取精髓。
Effective Java里说,当遇到多个构造器参数时,考虑用构造器模式。里面有个商品的例子。这让我想到了熟悉的学生信息管理系统。
拿研究生来说吧,入学考试后先进行面试和体检,然后是录取,最后是入学分班。这几个阶段对学生的信息需求是不一样的。
我们首先基于以下假设:
1、体检时只需要知道我们的姓名、性别、年龄和身高等信息。
2、录取的时候,需要在体检基本信息的基础上添加院系、年级等信息。
3、入学分班后,需要添加班号(班级编号)等信息。
4、正式开学后,为了便于管理,又需要完善身份证、学号、实验室名称和宿舍地址等信息。
好吧,现在我们动手写这个学生信息管理系统。先要创建一个名为Student的类,为了满足4个阶段创建用户信息的需要
,我们可能需要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;}}
package com.icecode.data;public class Student {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;//宿舍地址private Student(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 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;//宿舍地址public Builder(String name, int age, int height, int sex) {super();this.name = name;this.age = age;this.height = height;this.sex = sex;}public Builder setSchoolName(String schoolName) {this.schoolName = schoolName;return this;}public Builder setProfession(String profession) {this.profession = profession;return this;}public Builder setGradeNo(int gradeNo) {this.gradeNo = gradeNo;return this;}public Builder setIdCard(String idCard) {this.idCard = idCard;return this;}public Builder setStuNo(String stuNo) {this.stuNo = stuNo;return this;}public Builder setLabName(String labName) {this.labName = labName;return this;}public Builder setDormitoryAddress(String dormitoryAddress) {this.dormitoryAddress = dormitoryAddress;return this;}//构造器入口public Student build(){return new Student(this);}}@Overridepublic String toString() {return "Students [name=" + name + ", age=" + age + ", height=" + height+ ", sex=" + sex + ", schoolName=" + schoolName+ ", profession=" + profession + ", gradeNo=" + gradeNo + "]";}}
public class Test {public static void main(String[] args){Student stu = new Student.Builder("icecode", 22, 178, 1) .setSchoolName("BUPT").setProfession("Computer Science and Technology").setGradeNo(20091012).build();System.out.println(stu.toString());}}