一、概述
一般问题:在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
核心方案:将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
设计意图:通常情况,我们创建一个对象实例有两种方法:
- 简单的对象,一般调用带参数的构造函数,直接new一个实例
- 稍复杂对象,一般先调用空构造函数new一个实例,再通过setXXX()设置具体属性。
如果对象比较复杂,属性繁多,上述方法就显得力不从心,至少实现起来不够优雅。为了能更灵活优雅地创建复杂对象,借用建造者模式是个很好的选择。它将复杂对象的众多属性组合交给一个builder对象来完成,客户端可以用更简洁的语法实现对象创建。
二、应用示例
Android中最常见的Builder模式就是Dialog的创建。
private void showDialog(Context context) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setIcon(R.drawable.icon); //组装各个零件 builder.setTitle("Title"); builder.setMessage("Message"); builder.setPositiveButton("Button1", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { setTitle("Button1 Clicked"); } }); builder.setNeutralButton("Button2", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { setTitle("Button2 Clicked"); } }); builder.setNegativeButton("Button3", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { setTitle("Button3 Clicked"); } }); builder.create().show(); // Dialog 在Builder完成组装,输出AlertDialog并显示 }
一般Builder类以静态内部类的形式存在于所创建对象类中,下面看下Builder类:
public static class Builder { public Builder(Context context) { this(context, resolveDialogTheme(context, 0)); } //组装Title public Builder setTitle(int titleId) { P.mTitle = P.mContext.getText(titleId); return this; } //组装Icon public Builder setIcon(int iconId) { P.mIconId = iconId; return this; } //组装确认按钮 public Builder setPositiveButton(int textId, final OnClickListener listener) { P.mPositiveButtonText = P.mContext.getText(textId); P.mPositiveButtonListener = listener; return this; } //完成组装,输出AlertDialog 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; } //显示Dialog public AlertDialog show() { AlertDialog dialog = create(); dialog.show(); return dialog; } }
三、总结
总结:建造者模式是一种创建型设计模式,其目的是将复杂的构建过程封装在一个Builder对象中,从而使客户端可以更优雅地创建复杂对象,更灵活地组织对象属性。
用一句话表述建造者模式:
流水线?我们不一样
优点:
- 建造者独立,易扩展
- 构建与表示分离,要改变内部表示,只需再定义一个具体构造者
缺点:
- 产品构造过程须有边界
- 如内部表示变化复杂,会增加过多构造类