建造者模式是什么?
建造者模式,简单的说就是在创建对象的时候,不是通过new 来实现,而是通过一个builder对象的一系列操作,最终拼凑出一个你需要的对象,那么这么写的好处有哪些呢??是不是感觉到非常的麻烦?明明能够new一下就就解决的事情,为什么非得通过好几步完成呢?这不是画蛇填足么?
其实,他的存在是有一定需求道理的,那么什么时候才使用这种模式呢?
其实你仔细的想一下,如果我想new一个对象,你又想灵活的控制他的传入的参数,那么势必的你就需要创建多个不同的构造函数在里边,那么如果你的实体中有十个这样的参数,那么你new出来的对象至少得有十个构造方法才能在不同的情况下传入不同数量的参数,是不是感到非常的麻烦?如果使用builder模式,你只要创建出builder对象通过builder对象想传递什么参数就可以灵活的控制了,最经典的案例就是我能的alertdialog,就是使用的这种模式:我们来分析一下:
1,创建了dialog类,
2,类中定义内部类builder
3,builder内部类中定义构造,创建builder对象,
4,buidler对像有各种设置的方法,其实都是dialog中的方法,用他来取代,
5,每一个设置方法中返回的都是builder本身。这是最大的核心
6,通过每次返回自己,才能够进行链条是的跳转。
7,最后通过create方法返回的是dialog对象
8,这种设计模式的出现相当程度上减少了构造函数的重载,减少了代码的冗余,增加了灵活性。
public class AlertDialog extends Dialog implements DialogInterface {
private AlertController mAlert;
//构造函数。传入上下文对象
protected AlertDialog(Context context) {
this(context, resolveDialogTheme(context, 0), true);
}
//设置标题
@Override
public void setTitle(CharSequence title) {
super.setTitle(title);
mAlert.setTitle(title);
}
//设置内容
public void setMessage(CharSequence message) {
mAlert.setMessage(message);
}
//builder内部类
public static class Builder {
private final AlertController.AlertParams P;
private int mTheme;
//builder的构造函数,
public Builder(Context context, int theme) {
P = new AlertController.AlertParams(new ContextThemeWrapper(
context, resolveDialogTheme(context, theme)));
mTheme = theme;
}
//设置标题。传递给dialog,这里继续返回自己本身,用来继续以链的形式设置属性
public Builder setTitle(int titleId) {
P.mTitle = P.mContext.getText(titleId);
return this;
}
//设置内容传递给dialog
public Builder setMessage(CharSequence message) {
P.mMessage = message;
return this;
}
public Builder setOnCancelListener(OnCancelListener onCancelListener) {
P.mOnCancelListener = onCancelListener;
return this;
}
//create方法,最终将属性赋予dialog之后返回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);
...
return dialog;
}
show.方法,将dialog展示出来
public AlertDialog show() {
AlertDialog dialog = create();
dialog.show();
return dialog;
}
}
}
在类的内部,有一个内部类builder类,通过bulider类来控制了类中的各个成员变量的设置,在dialog类中,构造只需要一个就可以了,在builder中,最后通过一个create方法,返回了最后创建好的dialog对象,是不是非常的灵活呢?如果我们不用这种方式我们再来看一下得多么的麻烦,看一下下边的案例:
这里写了一个类,需求是在不同的情况下通过不同的参数创建出对象,需要创建n个构造方法。如果再多。。。。只能哭了。。。。看红色部分?假设有一个实体类,需要十个参数完成初始化,那么这种构造函数。。我只能呵呵。。了
public class MyTextWatcher implements TextWatcher {
private EditText editText;
private WatcherListener watcherListener;
private int max_length; //最大输入字数
private boolean forbiddeEmoji; //是否禁止输入表情
//普通输入框watcher
public MyTextWatcher(EditText editText){
super();
this.editText = editText;
}
//限制表情,但无需剩余字数监听回调
public MyTextWatcher(EditText editText, int max_length){
this(editText, max_length, null);
}
/**
* 输入法监听工具类构造函数
* @param editText 所需要监听的editText
* @param max_length editText限制输入长度
* @param watcherListener 剩余字数监听回调
*/
public MyTextWatcher(EditText editText, int max_length, WatcherListener watcherListener){
this(editText, false, max_length, null);
}
/**
* 输入法监听工具类构造函数
* @param editText 所需要监听的editText
* @param forbiddeEmoji 是否禁止输入表情
* @param max_length editText限制输入长度
* @param watcherListener
*/
public MyTextWatcher(EditText editText, boolean forbiddeEmoji, int max_length, WatcherListener watcherListener){
super();
this.forbiddeEmoji = forbiddeEmoji;
this.editText = editText;
this.max_length = max_length;
this.watcherListener = watcherListener;
}
。。。
}
说到这里你应该能够知道它存在的必要性了吧。