(一)模式概念
生成器模式,又叫建造者模式,指将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。当系统准备为用户提供一个内部结构复杂的对象,并且该对象的构造方法无法满足用户需求时,就可以使用生成器模式来构造这样的对象。
(二)模式结构
生成器模式一般包括四个组成部分:
1)生成器接口Builder:
为创建一个产品对象的各个部件指定抽象接口。
2)生成器实现者ConcreteBuilder:
实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个能返回创建对象的方法。
3)生成器使用者Director:
构造一个使用Builder接口的对象。(客户端往往就是Builder接口的使用对象,如例子中的执行过程)
4)产品Product:
表示被构造的复杂对象。
(三)Demo
以学校录入学生数据业务过程为例:
生成器接口
public interface StudentInfoBuilder {
public void setID(String $id); // 设置学号
public void setDepartment(String $department); // 设置专业
public void setName(String $name); // 设置姓名
public void setSex(String $sex); // 设置性别
public void setAge(String $age);// 设置年龄
Info buildDayStudentInfo(); // 返回全日制学生信息
Info buildNightStudentInfo(); // 返回夜校学生信息
}
生成器实现者
public class StudentInfoConcrete implements StudentInfoBuilder {
String id;
String department;
String name;
String sex;
String age;
Info info;
Info ninfo;
public StudentInfoConcrete() {
}
@Override
public void setID(String $id) {
// 如有学号设置逻辑,可在此处添加...
id = $id;
}
@Override
public void setDepartment(String $department) {
// 如有专业设置逻辑,可在此处添加...
department = $department;
}
@Override
public void setName(String $name) {
// 如有姓名设置逻辑,可在此处添加...
name = $name;
}
@Override
public void setSex(String $sex) {
// 如有性别设置逻辑,可在此处添加...
sex = $sex;
}
@Override
public void setAge(String $age) {
// 如有年龄设置逻辑,可在此处添加...
age = $age;
}
@Override
public Info buildDayStudentInfo() {
info = new DayStudentInfo();
info.setId(id);
info.setDepartment("(全日制)" + department);
info.setName(name);
info.setSex(sex);
info.setAge(age);
return info;
}
@Override
public Info buildNightStudentInfo() {
ninfo = new NightStudentInfo();
ninfo.setId(id);
ninfo.setDepartment("(夜校)" + department);
ninfo.setName(name);
return ninfo;
}
}
产品接口
public interface Info {
public String id = ""; // 学号
public String department = ""; // 专业
public String name = ""; // 姓名
public String sex = ""; // 性别
public String age = ""; // 年龄
public String getId();
public void setId(String id);
public String getDepartment();
public void setDepartment(String department);
public String getName();
public void setName(String name);
public String getSex();
public void setSex(String sex);
public String getAge();
public void setAge(String age);
}
产品
public class DayStudentInfo implements Info {
private String id; // 学号
private String department; // 专业
private String name = ""; // 姓名
private String sex = ""; // 性别
private String age = ""; // 年龄
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String getId() {
return id;
}
@Override
public void setId(String id) {
this.id = id;
}
@Override
public String getDepartment() {
return department;
}
@Override
public void setDepartment(String department) {
this.department = department;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public String getSex() {
return sex;
}
@Override
public void setSex(String sex) {
this.sex = sex;
}
}
public class NightStudentInfo implements Info {
private String id; // 学号
private String department; // 专业
private String name = ""; // 姓名
private String sex = ""; // 性别
private String age = "无要求"; // 年龄
@Override
public String getId() {
return id;
}
@Override
public void setId(String id) {
this.id = id;
}
@Override
public String getDepartment() {
return department;
}
@Override
public void setDepartment(String department) {
this.department = department;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public String getSex() {
return sex;
}
@Override
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String getAge() {
return age;
}
@Override
public void setAge(String age) {
this.age = age;
}
}
执行过程:
// 建造器获取相同的信息
StudentInfoConcrete stc = new StudentInfoConcrete();
stc.setID("03041013");
stc.setName("李华");
stc.setDepartment("计算机");
stc.setAge("20");
// 报考全日制时建造的学生信息
Info info = stc.buildDayStudentInfo();
System.out.println("学号:" + info.getId() + "|姓名:" + info.getName()
+ "|专业:" + info.getDepartment() + "|年龄:" + info.getAge());
// 报考夜校时建造的学生信息
Info ninfo = stc.buildNightStudentInfo();
System.out.println("学号:" + ninfo.getId() + "|姓名:" + ninfo.getName()
+ "|专业:" + ninfo.getDepartment() + "|年龄:" + ninfo.getAge());
执行结果:
学号:03041013|姓名:李华|专业:(全日制)计算机|年龄:20
学号:03041013|姓名:李华|专业:(夜校)计算机|年龄:无要求
(注)在实际编码过程中,对象的构造过程和创建往往是一起执行的,所以生成器模式较少见到。只有当某些系统要求对象的构造过程必须独立于创建该对象的类或者根据不同的生产者个性需求建造不同的产品时,才会用到生成器模式。