建造者模式( Builder 模式)
定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示;
使用场景:
- 相同的方法,不同的执行顺序,产生不同的事件结果时;
- 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同;
- 产品类非常复杂,或者产品类中的调用顺序不同产生了不同的作用,这个时候建造者模式就非常适合;
- 当初始化一个对象特别复杂,如参数多,且很多参数都是具有默认值时;
优点:
- 使用建造者模式可以使客户端不必知道产品内部组成的细节;
- 具体的建造者类之间是相互独立的,容易扩展;
- 由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生影响;
缺点: 产生多余的 Build 对象以及 Director 对象,消耗内存;
下面用个例子来帮助理解下:
1 创建产品类.
public class Computer {
private String mCpu;
private String mMainboard;
private String mRam;
public void setmCpu(String mCpu) {
this.mCpu = mCpu;
}
public void setmMainboard(String mMainboard) {
this.mMainboard = mMainboard;
}
public void setmRam(String mRam) {
this.mRam = mRam;
}
@Override
public String toString() {
return "Computer{" +
"mCpu='" + mCpu + '\'' +
", mMainboard='" + mMainboard + '\'' +
", mRam='" + mRam + '\'' +
'}';
}
}
2.创建 Builder 类规范产品的组建.
public abstract class Builder {
public abstract void buildCpu(String cpu);
public abstract void buildMainboard(String mainboard);
public abstract void buildRam(String ram);
public abstract Computer create();
}
public class MoonComputerBuilder extends Builder {
private Computer computer = new Computer();
@Override
public void buildCpu(String cpu) {
computer.setmCpu(cpu);
}
@Override
public void buildMainboard(String mainboard) {
computer.setmMainboard(mainboard);
}
@Override
public void buildRam(String ram) {
computer.setmRam(ram);
}
@Override
public Computer create() {
return computer;
}
}
Director 类来统一组装过程.
public class Direcror {
Builder builder = null;
public Direcror(Builder builder) {
this.builder = builder;
}
public Computer CreateComputer(String cpu,String mainboard,String ram){
this.builder.buildCpu(cpu);
this.builder.buildMainboard(mainboard);
this.builder.buildRam(ram);
return builder.create();
}
}
客户端调用 Director 类
public static void main(String[] args) {
Builder builder = new MoonComputerBuilder();
Direcror direcror = new Direcror(builder);
direcror.CreateComputer("i7","NB","三星");
}
值得注意的是, 在现实开发过程中, Director 角色经常会被忽略.而是直接使用一个 Builder 来进行对象的组装,这样的 Builder 通常为链式调用的,它的关键是每个 setter 方法都返回自身,也就是 return this , 这样就使得 setter 方法可以链式调用,大致如下:
new TestBuilder().setA("A").setB("B").create();
在 Android 开发中我们能想到的最常见的 Builder 模式 就是 AlertDialog.Builder, 使用该 Builder 来构建复杂的 AlertDialog 对象.
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setIcon(R.drawable.icon);
builder.setTitle("标题");
builder.setMessage("内容");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
setTitle("点击了确定");
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
setTitle("点击取消");
}
});
builder.create().show();
这个系统自带弹窗,相信每个 Android 开发者都用过,这个可以看出来 就是 Builder 模式,通过 Builder 对象来组装 Dialog 的各个部分,比如 title, button, message 等, 将Dialog 的构造和表示分离. 看下 AlertDialog 的源码就可以发现,的确使用的是 Builder 模式, Builder 作为内部类的形式在 AlertDialog 类中. 但是 Android 并没有完全按照 GOF 在 <设计模式:可复用面向对象软件的基础>一书中描述的经典模式来实现的,而是做了一些修改,使得这个模式更加易于使用,