Android 设计模式之Builder模式的简单使用
Android 设计模式之Builder模式的简单使用
一、Builder模式介绍
Builder 模式是一步一步创建一个复杂对象的创建型模式,它允许用户在不知道内部构建细节的情况下。可以精细地控制对象的构造流程。Builder模式将复杂对象的构建过程和他的部件解耦,使得构建过程和部件的表示隔离开来。
二、使用场景
相同的方法,但是有不同的执行顺序,产生了不同的结果
多个零件和部件都可以装配到一个对象中,但是产生的运行结果不同
初始化对象复杂,但是有很多默认的参数
三、结构图
Builder-抽象Builder类,规范产品的组建,一般是由子类实现具体的组建过程
ConcreteBuilder-具体的Builder类
Director-统一组装的过程
四、交互过程
client通过调用Director来创建不同的属性的对象,Director调用ConcreateBuilder创建所需属性的对象。层层封装,最终留给用户的只是一个调用的方法 Directo
五、简单的使用封装
下面是我使用Builder模式对Android AlertDialog的封装
在对象中调用,通过创建构造函数并调用showDialog()方法开启创建
final MyOwnAlertDialog myOwnAlertDialog = new MyOwnAlertDialog(context, activity, title, null, "确定", "取消");
myOwnAlertDialog.setOnDiaLogListener(new MyOwnAlertDialog.OnDialogListener() { @Override
public void dialogPositiveListener(View customView, DialogInterface dialogInterface, int which) { //dosomthing
} @Override
public void error(String msg) { //dosomthing
}
});
} @Override
public void dialogNegativeListener(View customView, DialogInterface dialogInterface, int which) {
}
}).showDialog();
}
}
});
构造器Builder,是构造一个使用Builder接口的对象:通过new CustomDialog.Builder 来创建对话框对象,并调用builder里的方法设置参数,创建一个一个的ConcreteBuilder产品
public class MyOwnAlertDialog { private Activity activity; private String dialogMessage; private String dialogTitle; private String positiveText; private String negativeText; private View dialogView; private int customeLayoutId; private Context context; private OnDialogListener listener; private CustomDialog.Builder dialog; //带有自定义view的构造器
public MyOwnAlertDialog(Context context, Activity activity, int customeLayoutId, String dialogTitle, String positiveText, String negativeText) { this.context = context; this.activity = activity; this.customeLayoutId = customeLayoutId; this.dialogTitle = dialogTitle; this.positiveText = positiveText; this.negativeText = negativeText; this.dialogView = View.inflate(context, customeLayoutId, null);
} //不带自定义view的构造器,
public MyOwnAlertDialog(Context context, Activity activity, String dialogMessage, String dialogTitle, String positiveText, String negativeText) { this.context = context; this.activity = activity; this.dialogTitle = dialogTitle; this.dialogMessage = dialogMessage; this.positiveText = positiveText; this.negativeText = negativeText;
} public void showDialog() {
dialog = new CustomDialog.Builder(context, activity);
dialog.setTitle(dialogTitle);//设置标题
//注意:dialogMessage和dialogView是互斥关系也就是dialogMessage存在dialogView就不存在,dialogView不存在dialogMessage就存在
if (dialogMessage != null) {
dialog.setMessage(dialogMessage);//设置对话框内容
} else {
dialog.setContentView(dialogView);//设置对话框的自定义view对象
} /**
* 尽管有两个点击事件监听器,可以通过我们自定义的监听器设置一个标记变量,从而可以实现将两个点击事件合并成一个
* 监听器OnDialogListener
* */
//确定意图传入positive标记值
dialog.setPositiveButton(positiveText, new DialogInterface.OnClickListener() { @Override
public void onClick(DialogInterface dialogInterface, int which) {
dialogInterface.dismiss(); if (listener != null) {
listener.dialogPositiveListener(dialogView, dialogInterface, which);
}
} //取消意图传入negative标记值
}).setNegativeButton(negativeText, new DialogInterface.OnClickListener() { @Override
public void onClick(DialogInterface dialogInterface, int which) {
dialogInterface.dismiss(); if (listener != null) {
listener.dialogNegativeListener(dialogView, dialogInterface, which);
}
}
}).create().show();
} //注册监听器方法
public MyOwnAlertDialog setOnDiaLogListener(OnDialogListener listener) { this.listener = listener; return this;//把当前对象返回,用于链式编程
} //定义一个监听器接口
public interface OnDialogListener { //customView 这个参数需要注意就是如果没有自定义view,那么它则为null
public void dialogPositiveListener(View customView, DialogInterface dialogInterface, int which); public void dialogNegativeListener(View customView, DialogInterface dialogInterface, int which);
}
}
ConcreteBuilder构建,基础的ConcreteBuilder,定义个体的方法
/**
* 建造者模式封装自定义dialog
* Created by david on 2016/12/21.
*/public class CustomDialog extends Dialog { private static CustomDialog dialog; public CustomDialog(Context context) { super(context);
} public CustomDialog(Context context, int themeResId) { super(context, themeResId);
} public static class Builder{ private Activity activity; private Context context; private String message; private String title; private View contentView; private String positiveButtonText; private String negativeButtonText; private OnClickListener positiveButtonClickListener; private OnClickListener negativeButtonClickListener; public Builder(Context context, Activity activity) { this.context = context; this.activity = activity;
} public Builder setMessage(String message) { this.message = message; return this;
} public Builder setMessage(int message) { this.message = (String) context.getText(message); return this;
} public Builder setTitle(int title) { this.title = (String) context.getText(title); return this;
} public Builder setTitle(String title) { this.title = title; return this;
} public Builder setContentView(View v) { this.contentView = v; return this;
} public Builder setPositiveButton(int positiveButtonText,
OnClickListener listener) { this.positiveButtonText = (String) context
.getText(positiveButtonText); this.positiveButtonClickListener = listener; return this;
} public Builder setPositiveButton(String positiveButtonText,
OnClickListener listener) { this.positiveButtonText = positiveButtonText; this.positiveButtonClickListener = listener; return this;
} public Builder setNegativeButton(int negativeButtonText,
OnClickListener listener) { this.negativeButtonText = (String) context
.getText(negativeButtonText); this.negativeButtonClickListener = listener; return this;
} public Builder setNegativeButton(String negativeButtonText,
OnClickListener listener) { this.negativeButtonText = negativeButtonText; this.negativeButtonClickListener = listener; return this;
} public CustomDialog create() {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); // instantiate the dialog with the custom Theme
dialog = new CustomDialog(context,R.style.Dialog);
View layout = inflater.inflate(R.layout.myownalertdialog_layout, null);
dialog.addContentView(layout, new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
DisplayMetrics dm = new DisplayMetrics(); //设置窗体大小
activity.getWindowManager().getDefaultDisplay().getMetrics(dm); int screenWidth = dm.widthPixels; int screenHeigh = dm.heightPixels; int heigh = screenHeigh * 7 / 30; int weight = screenWidth * 6 / 8;
android.view.Window window = dialog.getWindow();
window.setLayout(weight, heigh);
window.setBackgroundDrawableResource(R.drawable.dialog_shape); // set the dialog title
//((TextView) layout.findViewById(R.id.title)).setText(title);
// set the confirm button
if (positiveButtonText != null) {
((TextView) layout.findViewById(R.id.sure))
.setText(positiveButtonText); if (positiveButtonClickListener != null) {
((TextView) layout.findViewById(R.id.sure))
.setOnClickListener(new View.OnClickListener() { public void onClick(View v) {
positiveButtonClickListener.onClick(dialog,
DialogInterface.BUTTON_POSITIVE);
}
});
}
} else { // if no confirm button just set the visibility to GONE
/* layout.findViewById(R.id.back).setVisibility(
View.GONE);*/
} // set the cancel button
if (negativeButtonText != null) {
((TextView) layout.findViewById(R.id.cancle))
.setText(negativeButtonText); if (negativeButtonClickListener != null) {
((TextView) layout.findViewById(R.id.cancle))
.setOnClickListener(new View.OnClickListener() { public void onClick(View v) {
negativeButtonClickListener.onClick(dialog,
DialogInterface.BUTTON_NEGATIVE);
}
});
}
} else { // if no confirm button just set the visibility to GONE
/* layout.findViewById(R.id.cancle).setVisibility(
View.GONE);*/
} // set the content message
if (message != null) {
((TextView) layout.findViewById(R.id.alert2_title)).setText(message);
} else if (contentView != null) { // if no message set
// add the contentView to the dialog body
((LinearLayout) layout.findViewById(R.id.content))
.removeAllViews();
((LinearLayout) layout.findViewById(R.id.content)).addView(
contentView, new ActionBar.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT));
}
dialog.setContentView(layout); return dialog;
}
}
}
上述示例中,通过具体的CustomDialog来封装具体的内容,通过MyOwnAlertDialog来构建具体的对象,他们一起将一个复杂对象的构建和他的表示分离,使得同样的构建过程可以创建不同的对象
六、总结
Builder模式在各类开发中都比较常见,通常作为配置类的构建器将配置的构建和表示分离开来,同时也是将配置从目标类分离出来,避免过多的方法, 有良好的封装性,使得代码易修改,独立,容易扩展
React/React-Native/Flux/Redux/跨平台项目实战 6天魔鬼训练
扫描二维码
关注更多精彩