建造者模式是什麼?
建造者模式,簡單的說就是在創建對象的時候,不是通過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;
}
。。。
}
說到這裏你應該能夠知道它存在的必要性了吧。