目录
- 简介重叠构造器
- JavaBeans 模式
- Builder 模式
- Builder 模式在 Android 的应用
简介
构造器和静态工厂有一定的局限性,当我们创建实例,遇到大量的参数,有的参数需要传值,有的参数不需要选择等等灵活的条件下,我们应该怎么办?
-
重叠构造器:简单粗暴,提供好多好多个构造函数来满足需要。
-
JavaBeans 模式:实际上是先调用无参的构造函数来创建对象,然后再调用属性的 setter 方法来设置每个必要的参数,以及每个可选参数。
-
Builder 模式:此模式不直接生成想要的对象。首先客户端使用必要的参数调用构造器(或静态工厂方法),得到一个builder对象;然后客户端在 builder 对象上调用类似于 setter 的方法来设置可选参数;最后调用无参的 build 方法来生成不可变的对象,这个builder是它构建的类的静态成员类。
重叠构造器
在这举个最简单的例子,学生类如下:
public class Student {
private String Name;
private int ID;
private int age;
private String MClass;
private String Phone;
private String address;
public Student(String name, int iD) {
this(name,iD,0);
}
public Student(String name, int iD, int age) {
this(name,iD,age,"软件工程班");
}
public Student(String name, int iD, int age, String mClass) {
this(name,iD,age,mClass,"0");
}
public Student(String name, int iD, int age, String mClass, String phone) {
this(name,iD,age,mClass,phone,"China");
}
public Student(String name, int iD, int age, String mClass, String phone,String address) {
this.Name = name;
this.ID = iD;
this.age = age;
this.MClass = mClass;
this.Phone = phone;
this.address = address;
}
}
当我们想要创建实例时,我们必须要传入必要参数 Name 和 ID ,如下:
Student mStudent=new Student("pm", 12345678);
当我们需要再传入 Address 的值时,好多参数我们不得不为其传入默认值,这样看起来…就算恶心还没得家吧,如果再增加6个参数,并且需要灵活选择参数,那么构造函数就炸了…
Student mStudent2=new Student("pm", 12345678,0,"","","青岛市");
一句话:遇到很多参数时,重叠构造器可行,但是代码会很难编写,而且难以阅读。
JavaBeans模式
把学生类改成这样:
public class Student {
private String Name;
private int ID;
private int age;
private String MClass;
private String Phone;
private String address;
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public void setID(int iD) {
ID = iD;
}
public void setAge(int age) {
this.age = age;
}
public void setMClass(String mClass) {
MClass = mClass;
}
public void setPhone(String phone) {
Phone = phone;
}
public void setAddress(String address) {
this.address = address;
}
}
这种模式弥补了构造器模式的不足,创建实例很容易,可读性也不错。
Student mStudent=new Student();
mStudent.setName("pm");
mStudent.setID(12345678);
mStudent.setAddress("青岛市");
据书中说…
javaBeans模式自身存在着严重缺点:
- 在构造过程中,被分到了几个调用中,JavaBeans可能处于不一致的状态,使用处于不一致状态的对象,将会产生错误。
- JavaBeans模式阻止了把类做成不可变的可能,这就需要程序猿尽力确保线程安全。
一句话:这种模式很少使用。
Builder 模式
把学生类再改成这样:
public class Student {
private final String name;
private final int ID;
private final int age;
private final String mClass;
private final String phone;
private final String address;
/**
* 学生类的静态成员类
*
* @author GUOFENG
*
*/
public static class Bulider {
private final String name;
private final int ID;
private int age = 0;
private String mClass = null;
private String phone = null;
private String address = null;
public Bulider(String name, int id) {
this.name = name;
this.ID = id;
}
public Bulider age(int a) {
age = a;
return this;
}
public Bulider mClass(String c) {
mClass = c;
return this;
}
public Bulider phone(String p) {
phone = p;
return this;
}
public Bulider address(String add) {
address = add;
return this;
}
public Student bulid() {
return new Student(this);
}
}
/**
* 把上面设置好的bulider抠出来
*
* @param bulider
*/
private Student(Bulider bulider) {
name = bulider.name;
ID = bulider.ID;
age = bulider.age;
mClass = bulider.mClass;
phone = bulider.phone;
address = bulider.address;
}
}
想怎么设置就怎么设置,想怎么玩就怎么玩:
Student mStudent = new Student.Bulider("pm", 12345678).address("青岛市").bulid();
既保证像重叠构造器那样的安全性,也保证有着 javaBeans 模式的可读性。
一句话:设计类,构造器或者静态工厂中具有多个参数,Builder模式是不错的选择。
Builder 模式在 Android 的应用
在 android 编程中,使用当然也是特别广泛,比如,通过 Notification.Builder 创建通知的代码片段:
Notification.Builder myBuilder = new Notification.Builder(context);
myBuilder.setContentTitle(context.getString(R.string.app_name))
.setContentText(content)
.setTicker("您收到新的 " + context.getString(R.string.app_name) + " 消息")
.setSmallIcon(R.mipmap.ic_launcher)
.setAutoCancel(true)//点击后取消
.setWhen(System.currentTimeMillis())//设置通知时间
.setPriority(Notification.PRIORITY_HIGH)//高优先级
.setContentIntent(pi); //3.关联PendingIntent
Notification mNotification= myBuilder.build();
…