簡介:
設計模式的類型
創建型模式:
這些設計模式提供了一種在創建對象的同時隱藏創建邏輯的方式,而不是使用new運算符直接實例化對象。這使得程序在判斷針對某個給定實例需要創建哪些對象時更加靈活。
常見的這類設計模式有工廠模式、抽象工廠模式、單例模式、建造者模式、原型模式。
結構性模式:
這些設計模式關注和對象的組合,繼承的概念被用來組合接口和定義組合對象獲得新功能的方式。
常見的這類設計模式有適配器模式、橋接模式、過濾器模式、組合模式、裝飾器模式、代理模式等。
行爲型模式:
這些設計模式特別關注對象之間的通信和對象的行爲。
常見的這類設計模式有責任鏈模式、解釋器模式、迭代器模式、中介者模式、觀察者模式、訪問者模式等。
Builder模式/建造者模式:
建造者模式使用多個簡單的對象一步一步構建成一個複雜的對象。這種類型的設計模式屬於創建型模式,它提供了一種創建對象的最佳方式。一個Builder類會一步一步構造最終的對象,該Builder類是獨立於其他對象的。
Android中的使用:
builder模式在android中的使用場景還是挺多了,常見的就有AlertDialog的創建過程。
AlertDialog.Builder builder = new AlertDialog.Builder(this)
.setTitle("title")
.setCancelable(true)
.setIcon(R.mipmap.ic_launcher)
.setMessage("this is a message");
builder.create().show();
爲了更好地分析builder模式的使用,接下來我們可以分析下android系統的開發者是如何運用的。以AlertDialog爲例,首先我們可以看到這裏的builder是AlertDialog的一個靜態內部類。
public class AlertDialog extends AppCompatDialog implements DialogInterface {
......
public static class Builder {
private final AlertController.AlertParams P;
private final int mTheme;
public Builder(@NonNull Context context) {
this(context, resolveDialogTheme(context, 0));
}
public Builder(@NonNull Context context, @StyleRes int themeResId) {
P = new AlertController.AlertParams(new ContextThemeWrapper(
context, resolveDialogTheme(context, themeResId)));
mTheme = themeResId;
}
@NonNull
public Context getContext() {
return P.mContext;
}
......
public Builder setTitle(@Nullable CharSequence title) {
P.mTitle = title;
return this;
}
public Builder setMessage(@Nullable CharSequence message) {
P.mMessage = message;
return this;
}
public Builder setIcon(@Nullable Drawable icon) {
P.mIcon = icon;
return this;
}
......
public AlertDialog create() {
// We can't use Dialog's 3-arg constructor with the createThemeContextWrapper param,
// so we always have to re-set the theme
final AlertDialog dialog = new AlertDialog(P.mContext, mTheme);
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;
}
public AlertDialog show() {
final AlertDialog dialog = create();
dialog.show();
return dialog;
}
}
}
可以看到這裏的builder在初始化構造函數中創建了一個AlertController.AlertParams對象,並持有了它的引用p。而這個對象就是用來管理AlertDialog創建時各個複雜的屬性的。比如builder中的setTitle方法就是對p.mTitle屬性進行賦值,其他的屬性也是如此,然後在返回自身this,使之可以形成鏈式調用。最後通過builder.create()方法創建出AlertDialog對象並將p中的屬性應用給AlertDialog。至此AlertDialog這個複雜的創建過程就通過簡單的鏈式調用完成了。而我們用的時候也不需要對所有的屬性進行賦值,只需要關心用的到的即可。