Builder模式
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
对象创建需要的属性多,而且不固定,为了简化创建过程,在对象类创建指定对象各个属性抽象接口。
实现方式
public static class Builder {
public Builder() {
}
public Builder setTitle(String titleId) {
parent.mTitle = titleId;
return this;
}
public Builder setContent(String content) {
parent.mContent = content;
return this;
}
}
在创建时,按需求set对应属性
Android中的Builder模式
AlertDialog.Builder
简单示例如下
private void showDialog(Context context) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setIcon(R.drawable.icon).setTitle("Title").setMessage("Message")
.create().show(); // 构建AlertDialog, 并且显示
}
AlertDialog源码
// AlertDialog
public class AlertDialog extends Dialog implements DialogInterface {
// Controller, 接受Builder中的各个参数
private AlertController mAlert;
// 构造函数,所有构造函数都不是public,外界只能通过builder创建实例
protected AlertDialog(Context context, int theme) {
this(context, theme, true);
}
//AlertDialog实现都没有创建AlertDialog,而是AlertController
AlertDialog(Context context, int theme, boolean createThemeContextWrapper) {
super(context, resolveDialogTheme(context, theme));
mAlert = new AlertController(getContext(), this, getWindow());
}
……
//设置AlertDialog属性,实际通过AlertController设置
@Override
public void setTitle(CharSequence title) {
super.setTitle(title);
mAlert.setTitle(title);
}
public void setMessage(CharSequence message) {
mAlert.setMessage(message);
}
public static class Builder {
//存储AlertDialog的属性
private final AlertController.AlertParams P;
private int mTheme;
/*
Builder构造函数
*/
public Builder(Context context) {
this(context, resolveDialogTheme(context, 0));
}
public Builder(Context context, int theme) {
P = new AlertController.AlertParams(new ContextThemeWrapper(
context, resolveDialogTheme(context, theme)));
mTheme = theme;
}
// 设置各种属性
public Builder setTitle(CharSequence title) {
P.mTitle = title;
return this;
}
public Builder setMessage(CharSequence message) {
P.mMessage = message;
return this;
}
//AlertDialog创建
public AlertDialog create() {
// 创建AlertDialog
final AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false);
// 将P中的属性传给mAlert
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;
}
}
P.apply(dialog.mAlert)代码中的AlertController.apply()方法
public void apply(AlertController dialog) {
if (mCustomTitleView != null) {
dialog.setCustomTitle(mCustomTitleView);
} else {
if (mTitle != null) {
dialog.setTitle(mTitle);
}
if (mIcon != null) {
dialog.setIcon(mIcon);
}
if (mIconId != 0) {
dialog.setIcon(mIconId);
}
if (mIconAttrId != 0) {
dialog.setIcon(dialog.getIconAttributeResId(mIconAttrId));
}
}
if (mMessage != null) {
dialog.setMessage(mMessage);
}
if (mPositiveButtonText != null) {
dialog.setButton(DialogInterface.BUTTON_POSITIVE, mPositiveButtonText,
mPositiveButtonListener, null);
}
if (mNegativeButtonText != null) {
dialog.setButton(DialogInterface.BUTTON_NEGATIVE, mNegativeButtonText,
mNegativeButtonListener, null);
}
if (mNeutralButtonText != null) {
dialog.setButton(DialogInterface.BUTTON_NEUTRAL, mNeutralButtonText,
mNeutralButtonListener, null);
}
if ((mItems != null) || (mCursor != null) || (mAdapter != null)) {
createListView(dialog);
}
if (mView != null) {
if (mViewSpacingSpecified) {
dialog.setView(mView, mViewSpacingLeft, mViewSpacingTop, mViewSpacingRight,
mViewSpacingBottom);
} else {
dialog.setView(mView);
}
} else if (mViewLayoutResId != 0) {
dialog.setView(mViewLayoutResId);
}
}
builder中设置属性值,然后在create中把值传给AlertDialog的AlertController,虽然实际实例化一个对象变复杂了,但是操作上的代码简单易读。比起new class的方法更加直观。