我尽量不打错别字,用词准确,不造成阅读障碍。
构造者模式是我知道的设计模式中在单例模式后最简单的模式,入门理解很简单。
解释:将一个复杂对象的构造与它的表示分离,使得同样的构造过程可以创建不同的表示。
表现形式:链式调用。
构造者模式可以用来做工具类的使用,还可以有效解决传递参数过多的情况。
概念难理解,举例(Android),把例子看明白了再回头看看概念其实最合适:
AlertDialog
AlertDialog dialog = new AlertDialog.Builder(this)
.setIcon(...)
.setTitle("...")
.setPositiveButton(...)
.setNegationButton(...)
.create();
dialog.show();
OKHttp
OkHttpClient.Builder httpBuilder = new OkHttpClient.Builder();
OkHttpClient client = httpBuilder.connectTimeout(50, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
简单明了的链式调用。
手写简单构造者
手写一个构造者,以自定义Dialog为例。
public class DialogUtil extend Dialog{
private Context mContext;
private int img;
private String content;
private boolean CancelOnTouchOutside = true;
private DialogUtil(DialogBuilder builder){
super(builder.context);
}
//可以设置style
private DialogUtil2(DialogBuilder builder, int style) {
super(builder.context, style);
mContext = builder.context;
img = builder.img;
text = builder.text;
CanceledOnTouchOutside = builder.CanceledOnTouchOutside;
}
//重写onCreate方法
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = View.inflate(mContext, R.layout.dialog_result, null); //自定义布局
ImageView img_view = (ImageView) view.findViewById(R.id.iv_img);
TextView text_view = (TextView) view.findViewById(R.id.tv_text);
img_view.setImageResource(img);
text_view.setText(content);
setContentView(view);
Window win = getWindow();
WindowManager.LayoutParams lp = win.getAttributes();
setCanceledOnTouchOutside(CanceledOnTouchOutside);
lp.gravity = Gravity.CENTER;
}
//重写show方法
@Override
public void show() {
super.show();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);//显示2秒后自动消失,视情况修改方法
dismiss();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
public static class DialogBuilder {
private Context context;
private String content = "操作成功";
private int img;
private boolean CanceledOnTouchOutside = true;
private int style = -1;
public DialogBuilder(Context context) {
this.context = context;
img= R.drawable.toast_1;
}
public Builder setText(String content) {
this.context = content;
return this; //重要的是这句
}
public Builder setImg(int imgResource) {
this.img = imgResource;
return this;
}
public void setCanceledOnTouchOutside(boolean canceledOnTouchOutside) {
CanceledOnTouchOutside = canceledOnTouchOutside;
}
public Builder setStyle(int style) {
this.style = style;
return this;
}
public DialogUtil2 build() {
if (style != -1) {
return new DialogUtil2(this, style);
} else {
return new DialogUtil2(this);
}
}
}
}
使用:
DialogUtil2.DialogBuilder builder = new DialogUtil2.DialogBuilder(this);
builder.setText("xxxxxx").setStyle(R.style.loading_dialog).build().show();
效果:
总体过程是这样的:直接new一个DialogUtil的内部类Builder,将想要添加的内容设置到Builder的属性中去,每次设置属性时通过return this;的方式返回builder对象,所有属性设置完成后,通过build方法new外部类的对象并将builder对象传递进去,然后在构造方法中将builder的属性设置到外部类的属性中去,最后调用外部类的show()方法显示。
理论解释:
上面的举例其实不能很好的解释构造者模式的构成,只是开发中经常这么写,我觉得从日常开发角度理解可以快速入门,之后才是深层次的理解。实际上构造者模式由四部分构成:Builder(抽象建造者)、ConcreteBuilder(具体建造者)、Product(产品)、Director(指挥者)。
Builder:是为创建一个Product对象的各个部件指定的抽象接口,本例中并没有写,因为写了内部类。
ConcreteBuilder:具体建造者,实现Builder接口,构造和装配各个部件,本例中的DialogBuilder。
Product:具体的产品,本例中的并不容易看出来,实际上是具体的Dialog,我们的最终目的就是建造出Dialog。
Director:构建一个使用Builder接口的对象,本例中的DialogUtil2。
怎么理解概念:将一个复杂对象的构造与它的表示分离,使得同样的构造过程可以创建不同的表示。
在上例中的意思就是,我想要创造一个画着”x”符号的dialog,并写上“操作失败”,直接重新new一个DialogUtil2.DialogBuilder(this)就好了,这样就改变了内部表示,而具体的建造方式和建造流程却没有丝毫改变
总觉得写的不好,本人实际开发中主要是Android中使用,所以举例Android,举例虽然不能很好的诠释传统建造者模式,但是在Android中比较常见,所以还是决定这个例子,也就做个入门使用理解。