本文是Android面試題整理中的一篇,結合右下角目錄食用更佳
1. 單例模式
一個類僅有一個例項,供全域性訪問,以下是幾種實現方式
//餓漢模式
public class Singleton{
private static Singleton instance = new Singleton();
private Singleton(){};
public Singleton getInstance(){
return instance;
}
}
// 懶漢模式
public class Singleton{
private volatile static Singleton instance = null;
private Singleton(){};
public Singleton getInstance(){
if(instance == null){
synchronized(Singleton.class){
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
//靜態內部類(推薦)
public class Singleton{
private static class SingletonHolder{
public static Singleton instance = new Singleton();
}
private static Singleton instance = new Singleton();
private Singleton(){};
public Singleton getInstance(){
return SingletonHolder;
}
}
複製程式碼
1.X 單例如何防止反射攻擊
- 使用一個static的標記位,再次實力化時驗證其值,丟擲異常
- 或者使用列舉
2. 建造者(Builder)模式
將物件的構建與展示分離,允許使用者在不知道內部構建細節的情況下,可以更精細地控制物件的構造流程。
Android中典型的用到Builder的地方是AlertDialog,以下是構建AlertDialog舉例
//顯示基本的AlertDialog
private void showDialog(Context context) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setIcon(R.drawable.icon);
builder.setTitle("Title");
builder.setMessage("Message");
builder.setPositiveButton("Button1",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
setTitle("點選了對話方塊上的Button1");
}
});
builder.setNeutralButton("Button2",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
setTitle("點選了對話方塊上的Button2");
}
});
builder.setNegativeButton("Button3",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
setTitle("點選了對話方塊上的Button3");
}
});
builder.create().show(); // 構建AlertDialog, 並且顯示
}
複製程式碼
3. 觀察者模式
觀察者模式在物件間建立了一對多的關係,當一個物件狀態發生改變時,通知和它關聯的所有物件它的改變,讓這些物件作出相應的調整。
在Android中,我們往ListView新增資料後,都會呼叫Adapter的notifyDataChanged()方法,其中使用了觀察者模式:當ListView的資料發生變化時,呼叫Adapter的notifyDataSetChanged函式,這個函式又會呼叫DataSetObservable的notifyChanged函式,這個函式會呼叫所有觀察者(AdapterDataSetObserver)的onChanged方法,在onChanged函式中又會呼叫ListView重新佈局的函式使得ListView重新整理介面
4. 代理(Proxy)模式
適用場景:被代理的物件A不能直接訪問或者出於對A的保護,不想讓它被直接訪問
給某一個物件A建立一個代理物件B,通過控制B來間接控制A,B與A實現了同一個介面。
- 代理可以分為靜態代理和動態代理。使用動態代理時我們需要實現中介類(實現InvocationHandler介面),並呼叫Proxy.newProxyInstance方法幫助我們動態生成一個代理。
- Android 的 Binder 中就運用了代理模式
5. 裝飾者模式
裝飾模式動態的將責任附加到物件上,若要擴充套件功能,裝飾模式提供了比繼承更有彈性的替代方案
6. 代理和裝飾的區別
代理強調限制,裝飾強調增強原有功能
7. 介面卡模式
將一個類的介面A轉換成客戶希望的另一個介面B。介面卡模式使得原本由於介面不相容而不能一起工作的那些類可以一起工作
8. 工廠和抽象工廠
- 簡單工廠將物件生成的過程進行了封裝9
- 工廠方法根據依賴倒置原則,將物件建立的過程交給子類
- 抽象工廠是為了生成一族物件,例如有一個生成一套服裝的工廠(生產上衣和褲子),它的實現有休閒工廠/正裝工廠;這個時候如果我們生成一個休閒工廠例項,並需要紅上衣綠褲子,那麼產出的是休閒紅上衣+休閒綠褲子
9. 命令模式
命令中包含接受者和一些資訊,Client建立命令,並將其交給執行者,執行者不必知道命令的細節,只需呼叫excute執行,命令會呼叫接受者執行。
10. 外觀模式
外觀模式提供了一個統一的介面,來訪問子系統的一群介面:實現了客戶和子系統的解偶
11. 原型模式
當建立物件的成本較大時,我們可以選擇原型模式,通過clone已經存在的物件生成一個新的物件
12. 責任鏈模式
對一個請求,用一條連結串列來處理,連結串列上每一個節點都有可能消耗掉這個請求或者繼續傳遞給後邊的節點
Android 中的有序廣播和View的事件分發是典型的責任鏈模式
13. 模版方法
在一個方法中定義一個演算法骨架,而將一些步驟延遲到子類中。
14. 策略模式
策略模式定義了一系列的演算法,並將每一個演算法封裝起來,而且使他們可以相互替換,讓演算法獨立於使用它的客戶而獨立變化
如安卓動畫中的插值器
15. 組合模式
將物件組合成樹形結構以表示“部分-整體”的層次結構,單個物件和物件的組合實現了同一個介面,組合模式使得使用者對單個物件和組合物件的使用具有一致性。
Android中典型的例子View,具體的View和ViewGroup都實現了View介面,同時可以將多個View新增到一個ViewGroup作為一個整體View。
16. 享元模式
享元模式是為數不多的、只為提升系統效能而生的設計模式。它的主要作用就是複用大物件(重量級物件),以節省記憶體空間和物件建立時間。
如Andrid 中 Message m = Message.obtain(); 用的就是享元模式
17. Activity中的設計模式
- 模版方法:生命週期
- 裝飾者:ContextWrapper內部有個Context引用mContext
- 直譯器:Manifest中定義Activity
- 備忘錄:Activity的onSaveInstanceState和onRestoreInstanceState