建造者模式:是将一个复杂的对象的构建与它的表示分离(同构建不同表示),使得同样的构建过程可以创建不同的表示。
一个人活到70岁以上,都会经历这样的几个阶段:婴儿,少年,青年,中年,老年。并且每个人在各个阶段肯定是不一样的,世界上不存在两个人在人生的这5个阶段的生活完全一样,但是活到70岁以上的人,都经历了这几个阶段是肯定的。实际上这是一个比较经典的建造者模式的例子了。
将复杂的内部创建封装在内部,对于外部调用的人来说,只需要传入建造者和建造工具,对于内部是如何建造成成品的,调用者无需关心。
建造者模式通常包括下面几个角色:
① Builder:一个抽象接口,用来规范产品对象的各个组成成分的建造。
② ConcreteBuilder:实现Builder接口,针对不同的商业逻辑,具体化复杂对象的各部分的创建,在建造过程完成后,提供产品的实例。
③ Director:指导者,调用具体建造者来创建复杂对象的各个部分,不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。
④ Product:要创建的复杂对象。
与抽象工厂的区别:在建造者模式里,有个指导者,由指导者来管理建造者,用户是与指导者联系的,指导者联系建造者最后得到产品。即建造模式可以强制实行一种分步骤进行的建造过程。
Product和产品的部分Part接口
public interface Product { }
public interface Part { }
Builder:
public interface Builder {
void buildPartOne();
void buildPartTwo();
Product getProduct();
}
ConcreteBuilder:
//具体建造工具
public class ConcreteBuilder implements Builder {
Part partOne, partTwo;
public void buildPartOne() {
//具体构建代码
};
public void buildPartTwo() {
//具体构建代码
};
public Product getProduct() {
//返回最后组装的产品
};
}
Director :
public class Director {
private Builder builder;
public Director( Builder builder ) {
this.builder = builder;
}
public void construct() {
builder.buildPartOne();
builder.buildPartTwo();
}
}
建造:
ConcreteBuilder builder = new ConcreteBuilder();
Director director = new Director(builder);
//开始各部分建造
director.construct();
Product product = builder.getResult();
优点:
客户端不必知道产品内部组成的细节。
具体的建造者类之间是相互独立的,对系统的扩展非常有利。
由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。
使用场合:
创建一些复杂的对象时,这些对象的内部组成构件间的建造顺序是稳定的,但是对象的内部组成构件面临着复杂的变化。
要创建的复杂对象的算法,独立于该对象的组成部分,也独立于组成部分的装配方法时。
Android中的Builder
android中的Dialog就使用了Builder Pattern,下面来看看AlertDialog的部分源码。
public static class Builder {
private final AlertController.AlertParams P;
private int mTheme;
public Builder(Context context, int theme) {
P = new AlertController.AlertParams(new ContextThemeWrapper(
context, resolveDialogTheme(context, theme)));
mTheme = theme;
}
AlertDialog的Builder 是一个静态内部类,没有定义Builder 的抽象接口。
对AlertDialog设置的属性会保存在Build类的成员变量P(AlertController.AlertParams)中。
Builder类中部分方法:
public Builder setTitle(int titleId) {
P.mTitle = P.mContext.getText(titleId);
return this;
}
public Builder setMessage(int messageId) {
P.mMessage = P.mContext.getText(messageId);
return this;
}
public Builder setPositiveButton(CharSequence text, final OnClickListener listener) {
P.mPositiveButtonText = text;
P.mPositiveButtonListener = listener;
return this;
}
而show()方法会返回一个结合上面设置的dialog实例
public AlertDialog show() {
AlertDialog dialog = create();
dialog.show();
return dialog;
}
}
}
public AlertDialog create() {
final AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false);
P.apply(dialog.mAlert);
dialog.setCancelable(P.mCancelable);
if (P.mCancelable) {
dialog.setCanceledOnTouchOutside(true);
}
dialog.setOnCancelListener(P.mOnCancelListener);
dialog.setOnDismissListener(P.mOnDismissListener);
if (P.mOnKeyListener != null) {
dialog.setOnKeyListener(P.mOnKeyListener);
}
return dialog;
}
简单建造:
new AlertDialog.Builder(context)
.setTitle("标题")
.setMessage("消息框")
.setPositiveButton("确定", null)
.show();
参考文献:设计模式之生成器模式(Builder Pattern)