單例模式能夠說是最容易理解的模式了,也是應用最廣的模式之一,先看看定義吧。java
定義:確保單例類只有一個實例,而且這個單例類提供一個函數接口讓其餘類獲取到這個惟一的實例。算法
何時須要使用單例模式呢:若是某個類,建立時須要消耗不少資源,即new出這個類的代價很大;或者是這個類佔用不少內存,若是建立太多這個類實例會致使內存佔用太多。數據庫
關於單例模式,雖然很簡單,無需過多的解釋,可是這裏還要提個醒,其實單例模式裏面有不少坑。咱們去會會單例模式。最簡單的單例模式以下:設計模式
public class Singleton{ private static Singleton instance; //將默認的構造函數私有化,防止其餘類手動new private Singleton(){}; public static Singleton getInstance(){ if(instance==null) instance=new Singleton(); return instatnce; } }
若是是單線程下的系統,這麼寫確定沒問題。但是若是是多線程環境呢?這代碼明顯不是線程安全的,存在隱患:某個線程拿到的instance
多是null
,可能你會想,這有什麼可貴,直接在getInstance()
函數上加sychronized
關鍵字不就行了。但是你想過沒有,每次調用getInstance()
時都要執行同步,這帶來不必的性能上的消耗。注意,在方法上加sychronized
關鍵字時,一個線程訪問這個方法時,其餘線程沒法同時訪問這個類其餘sychronized
方法。的咱們看看另一種實現:安全
public class Singleton{ private static Singleton instance; //將默認的構造函數私有化,防止其餘類手動new private Singleton(){}; public static Singleton getInstance(){ if(instance==null){ sychronized(Singleton.class){ if(instance==null) instance=new Singleton(); } } return instatnce; } }
爲何須要2次判斷是否爲空呢?第一次判斷是爲了不沒必要要的同步,第二次判斷是確保在此以前沒有其餘線程進入到sychronized塊建立了新實例。這段代碼看上去很是完美,可是,,,卻有隱患!問題出如今哪呢?主要是在instance=new Singleton();
這段代碼上。這段代碼會編譯成多條指令,大體上作了3件事:微信
(1)給Singleton實例分配內存
(2)調用Singleton()構造函數,初始化成員字段
(3)將instance對象指向分配的內存(此時instance就不是null啦~)網絡
上面的(2)和(3)的順序沒法獲得保證的,也就是說,JVM可能先初始化實例字段再把instance
指向具體的內存實例,也可能先把instance
指向內存實例再對實例進行初始化成員字段。考慮這種狀況:一開始,第一個線程執行instance=new Singleton();
這句時,JVM先指向一個堆地址,而此時,又來了一個線程2,它發現instance
不是null
,就直接拿去用了,可是堆裏面對單例對象的初始化並無完成,最終出現錯誤~ 。數據結構
看看另一種方式:多線程
public class Singleton{ private volatile static Singleton instance; //將默認的構造函數私有化,防止其餘類手動new private Singleton(){}; public static Singleton getInstance(){ if(instance==null){ sychronized(Singleton.class){ if(instance==null) instance=new Singleton(); } } return instatnce; } }
相比前面的代碼,這裏只是對instance
變量加了一個volatile
關鍵字volatile
關鍵字的做用是:線程每次使用到被volatile
關鍵字修飾的變量時,都會去堆裏拿最新的數據。換句話說,就是每次使用instance時,保證了instance是最新的。注意:volatile
關鍵字並不能解決併發的問題,關於volatile
請查看其它相關文章。可是volatile
能解決咱們這裏的問題。併發
那麼在安卓中哪些地方用到了單例模式呢?其實,咱們在調用系統服務時拿到的Binder對象就是個單例。好比:
//獲取WindowManager服務引用 WindowManager wm = (WindowManager)getSystemService(getApplication().WINDOW_SERVICE);
其內部是經過單例的方式返回的,因爲單例模式較簡單,這裏不去深究。
Builder模式是什麼狀況呢?我不想去提它的定義,由於他的定義:將一個複雜對象的構造與它的表示分離,使得一樣的構造過程能夠建立不一樣的表示。好吧,我仍是提了。可是看了這個定義並無什麼luan用。咱們看看具體在什麼狀況下用到Builder模式:主要是在建立某個對象時,須要設定不少的參數(經過setter方法),可是這些參數必須按照某個順序設定,或者是設置步驟不一樣會獲得不一樣結果。舉個很是簡單的例子:
public class MyData{ private int id; private String num; public void Test(){ } public void setId(int id){ this.id=id; } public void setNum(String num){ this.num=num+"id"; } }
固然了,沒有人會這麼去寫代碼。這裏只是舉例子,或者是有時候不少參數有這種相似的依賴關係時,經過構造函數未免太多參數了。回到主題,就是若是是上面的代碼,該怎麼辦呢?你可能會說,那還不簡單,先調用setId
函數,再調用setNum
函數。是的,沒錯。但是,萬一你一不當心先調用了setNum
呢?這是比較簡單的示例,若是是比較複雜的,有不少變量之間依賴的關係,那你每次都得當心翼翼的把各個函數的執行步驟寫正確。
咱們看看Builder模式是怎麼去作的:
public class MyBuilder{ private int id; private String num; public MyData build(){ MyData d=new MyData(); d.setId(id); d.setNum(num); return t; } public MyBuilder setId(int id){ this.id=id; return this; } public MyBuilder setNum(String num){ this.num=num; return this; } } public class Test{ public static void main(String[] args){ MyData d=new MyBuilder().setId(10).setNum("hc").build(); } }
注意到,Builer
類的setter
函數都會返回自身的引用this
,這主要是用於鏈式調用,這也是Builder
設計模式中的一個很明顯的特徵。
Android中用過的代碼來記憶
記憶我這個例子沒啥意義,咱們前面說過,要經過Android中用過的代碼來記憶,這樣才能夠不用死記硬背。那麼在Android中哪裏用到了Builder設計模式呢?哈哈~在建立對話框時,是否是跟上面有點相似呢?
AlertDialog.Builer builder=new AlertDialog.Builder(context); builder.setIcon(R.drawable.icon) .setTitle("title") .setMessage("message") .setPositiveButton("Button1", new DialogInterface.OnclickListener(){ public void onClick(DialogInterface dialog,int whichButton){ setTitle("click"); } }) .create() .show();
這裏的create()函數就想到上面代碼中的build函數。看到這裏是否是在心裏中默默的把Builder設計模式拿下了?你並不用死記硬背~
原型設計模式很是簡單,就是將一個對象進行拷貝。對於類A實例a,要對a進行拷貝,就是建立一個跟a同樣的類型A的實例b,而後將a的屬性所有複製到b。
何時會用到原型模式呢?我我的認爲,能夠在類的屬性特別多,可是又要常常對類進行拷貝的時候能夠用原型模式,這樣代碼比較簡潔,並且比較方便。
另外要注意的是,還有深拷貝和淺拷貝。深拷貝就是把對象裏面的引用的對象也要拷貝一份新的對象,並將這個新的引用對象做爲拷貝的對象引用。說的比較繞哈~,舉個例子,假設A類中有B類的引用b,如今須要對A類實例進行拷貝,那麼深拷貝就是,先對b進行一次拷貝獲得nb,而後把nb做爲A類拷貝的對象的引用,如此一層一層迭代拷貝,把全部的引用都拷貝結束。淺拷貝則不是。
原型模式比較簡單,看看Android怎麼運用原型模式:
Uri uri=Uri.parse("smsto:10086"); Intent shareIntent=new Intent(Intent.ACTION_SENDTO,uri); //克隆副本 Intent intent=(Intetn)shareIntent.clone(); startActivity(intent);
或許咱們平時不會這麼去寫,可是Intent
對象確實提供了原型模式的函數clone()
定義:定義一個建立對象的接口,讓子類決定實例化哪一個類
先看一個例子:
public abstract class Product{ public abstract void method(); } public class ConcreteProductA extends Prodect{ public void method(){ System.out.println("我是產品A!"); } } public class ConcreteProductB extends Prodect{ public void method(){ System.out.println("我是產品B!"); } } public abstract class Factory{ public abstract Product createProduct(); } public class MyFactory extends Factory{ public Product createProduct(){ return new ConcreteProductA(); } }
看到上面的代碼,是否是以爲工廠模式很簡單呢?還能夠經過傳參的方式,讓MyFactory的createProduct方法根據傳入的參數決定是建立ConcreteProductA仍是ConcreteProductB。
一樣的,咱們不但願記住這個例子,而是經過Android中的代碼來記憶:
其實,在getSystemService
方法中就是用到了工廠模式,他就是根據傳入的參數決定建立哪一個對象,固然了,因爲返回的都是以單例模式存在的對象,所以不用new了,直接把單例返回就好。
public Object getSystemService(String name) { if (getBaseContext() == null) { throw new IllegalStateException("System services not available to Activities before onCreate()"); } //........ if (WINDOW_SERVICE.equals(name)) { return mWindowManager; } else if (SEARCH_SERVICE.equals(name)) { ensureSearchManager(); return mSearchManager; } //....... return super.getSystemService(name); }
抽象工廠模式:爲建立一組相關或者是相互依賴的對象提供一個接口,而不須要制定他們的具體類
看個例子吧,將它跟工廠方法模式作個對比:
public abstract class AbstractProductA{ public abstract void method(); } public abstract class AbstractProdectB{ public abstract void method(); } public class ConcreteProductA1 extends AbstractProductA{ public void method(){ System.out.println("具體產品A1的方法!"); } } public class ConcreteProductA2 extends AbstractProductA{ public void method(){ System.out.println("具體產品A2的方法!"); } } public class ConcreteProductB1 extends AbstractProductB{ public void method(){ System.out.println("具體產品B1的方法!"); } } public class ConcreteProductB2 extends AbstractProductB{ public void method(){ System.out.println("具體產品B2的方法!"); } } public abstract class AbstractFactory{ public abstract AbstractProductA createProductA(); public abstract AbstractProductB createProductB(); } public class ConcreteFactory1 extends AbstractFactory{ public AbstractProductA createProductA(){ return new ConcreteProductA1(); } public AbstractProductB createProductB(){ return new ConcreteProductB1(); } } public class ConcreteFactory2 extends AbstractFactory{ public AbstractProductA createProductA(){ return new ConcreteProductA2(); } public AbstractProductB createProductB(){ return new ConcreteProductB2(); } }
其實Android源碼中對抽象工廠出現的比較少,好在抽象工廠方法並不複雜,很容易記住,咱們能夠從Service中去理解,Service的onBind方法能夠當作是一個工廠方法,從framework角度來看Service,能夠當作是一個具體的工廠,這至關於一個抽象工廠方法模式的雛形。
public class BaseService extends Service{ @Nullable @Override public IBinder onBind(Intent intent){ return new Binder(); } }
定義:有一系列的算法,將每一個算法封裝起來(每一個算法能夠封裝到不一樣的類中),各個算法之間能夠替換,策略模式讓算法獨立於使用它的客戶而獨立變化。
舉個例子來理解吧,好比,你如今又不少排序算法:冒泡、希爾、歸併、選擇等等。咱們要根據實際狀況來選擇使用哪一種算法,有一種常見的方法是,經過if...else或者case...等條件判斷語句來選擇。可是這個類的維護成本會變高,維護時也容易發生錯誤。
如何使用策略模式呢,我不打算寫示例代碼了,簡單描述一下,就將前面說的算法選擇進行描述。咱們能夠定義一個算法抽象類AbstractAlgorithm,這個類定義一個抽象方法sort()。每一個具體的排序算法去繼承AbstractAlgorithm類並重寫sort()實現排序。在須要使用排序的類Client類中,添加一個setAlgorithm(AbstractAlgorithm al);方法將算法設置進去,每次Client須要排序而是就調用al.sort()。
不知道簡單描述能不能讓你理解~
看看Android中哪裏出現了策略模式,其中在屬性動畫中使用時間插值器的時候就用到了。在使用動畫時,你能夠選擇線性插值器LinearInterpolator、加速減速插值器AccelerateDecelerateInterpolator、減速插值器DecelerateInterpolator以及自定義的插值器。這些插值器都是實現根據時間流逝的百分比來計算出當前屬性值改變的百分比。經過根據須要選擇不一樣的插值器,實現不一樣的動畫效果。這些比較好理解,就不去粘貼Android源碼了。
狀態模式中,行爲是由狀態來決定的,不一樣狀態下有不一樣行爲。狀態模式和策略模式的結構幾乎是如出一轍的,主要是他們表達的目的和本質是不一樣。狀態模式的行爲是平行的、不可替換的,策略模式的行爲是彼此獨立可相互替換的。
舉個例子把,好比電視,電視有2個狀態,一個是開機,一個是關機,開機時能夠切換頻道,關機時切換頻道不作任何響應。
public interface TvState{ public void nextChannerl(); public void prevChannerl(); public void turnUp(); public void turnDown(); } public class PowerOffState implements TvState{ public void nextChannel(){} public void prevChannel(){} public void turnUp(){} public void turnDown(){} } public class PowerOnState implements TvState{ public void nextChannel(){ System.out.println("下一頻道"); } public void prevChannel(){ System.out.println("上一頻道"); } public void turnUp(){ System.out.println("調高音量"); } public void turnDown(){ System.out.println("調低音量"); } } public interface PowerController{ public void powerOn(); public void powerOff(); } public class TvController implements PowerController{ TvState mTvState; public void setTvState(TvStete tvState){ mTvState=tvState; } public void powerOn(){ setTvState(new PowerOnState()); System.out.println("開機啦"); } public void powerOff(){ setTvState(new PowerOffState()); System.out.println("關機啦"); } public void nextChannel(){ mTvState.nextChannel(); } public void prevChannel(){ mTvState.prevChannel(); } public void turnUp(){ mTvState.turnUp(); } public void turnDown(){ mTvState.turnDown(); } } public class Client{ public static void main(String[] args){ TvController tvController=new TvController(); tvController.powerOn(); tvController.nextChannel(); tvController.turnUp(); tvController.powerOff(); //調高音量,此時不會生效 tvController.turnUp(); } }
在Android源碼中,哪裏有用到狀態模式呢?其實不少地方用到了,舉一個地方例子,就是WIFI管理模塊。當WIFI開啓時,自動掃描周圍的接入點,而後以列表的形式展現;當wifi關閉時則清空。這裏wifi管理模塊就是根據不一樣的狀態執行不一樣的行爲。因爲代碼太多,我就不手打敲入了~咱們只要知道大體Android裏面在哪裏用到了以及大概是怎麼用的就好。
定義:使多個對象都有機會處理請求,從而避免請求的發送者和接受者直接的耦合關係,將這些對象連成一條鏈,並沿這條鏈傳遞該請求,直到有對象處理它爲止。
相信聰明的你很容易理解吧,基本不須要例子來解釋了,直接進如到Android源碼中哪裏用到了責任鏈:在Android處理點擊事件時,父View先接收到點擊事件,若是父View不處理則交給子View,依次往下傳遞~
定義:給定一個語言,定義它的語法,並定義一個解釋器,這個解釋器用於解析語言。
從定義中看起來比較抽象,其實,很簡單,很容易理解!就是至關於自定義一個格式的文件,而後去解析它。不用理解的那麼複雜!
咱們看看Android中哪裏用到了,從咱們第一次學Android時就知道,四大組件須要在AndroidManifest.xml
中定義,其實AndroidManifest.xml
就定義了<Activity>
,<Service>
等標籤(語句)的屬性以及其子標籤,規定了具體的使用(語法),經過PackageManagerService(解釋器)進行解析。
定義:命令模式將每一個請求封裝成一個對象,從而讓用戶使用不一樣的請求把客戶端參數化;將請求進行排隊或者記錄請求日誌,以及支持可撤銷操做。
舉個例子來理解:當咱們點擊「關機」命令,系統會執行一系列操做,好比暫停事件處理、保存系統配置、結束程序進程、調用內核命令關閉計算機等等,這些命令封裝從不一樣的對象,而後放入到隊列中一個個去執行,還能夠提供撤銷操做。
那麼Android中哪裏用到了命令模式呢?在framework層還真很少。可是在底層卻用到了,一個比較典型的例子就是在Android事件機制中,底層邏輯對事件的轉發處理。每次的按鍵事件會被封裝成NotifyKeyArgs對象。經過InputDispatcher封裝具體的事件操做。
定義:定義了對象之間的一對多的關係,其實就是1對n,當「1」發生變化時,「n」所有獲得通知,並更新。
觀察者模式一個比較經典的應用就是:訂閱——發佈系統。很容易理解,發佈消息時,將消息發送給每一個訂閱者。咱們經常使用的微信公衆號就是典型,當咱們關注某個公衆號時,每當公衆號推送消息時,咱們就會去接收到消息,固然了,每一個訂閱(關注)公衆號的的人都能接收到公衆號推送的消息。
那麼Android哪裏用到了觀察者模式呢?咱們看看ListView的適配器,有個函數notifyDataSetChanged()
函數,這個函數其實就是通知ListView的每一個Item,數據源發生了變化,請各位Item從新刷新一下。
備忘錄模式定義:在不破壞封閉的前提下,捕獲一個對象的內部狀態,並在對象以外保存這個狀態,這樣,之後就可將對象恢復到原先保存的狀態中。
其實就是至關於一個提早備份,一旦出現啥意外,可以恢復。像咱們平時用的word軟件,意外關閉了,它能幫咱們恢復。其實就是它自動幫咱們備份過。
那麼Android哪裏用到了備忘錄模式呢?Activity
的onSaveInstanceState
和onRestoreInstanceState
就是用到了備忘錄模式,分別用於保存和恢復。
迭代器模式定義:提供一種方法順序訪問一個容器對象中的各個元素,而不須要暴露該對象的內部表示。
相信熟悉Java的你確定知道,Java中就有迭代器Iterator
類,本質上說,它就是用迭代器模式。
按照慣例,看看Android中哪裏用到了迭代器模式,Android源碼中,最典型的就是Cursor
用到了迭代器模式,當咱們使用SQLiteDatabase
的query
方法時,返回的就是Cursor
對象,經過以下方式去遍歷:
cursor.moveToFirst();
do{
//cursor.getXXX(int); }while(cursor.moveToNext);
定義:定義一個操做中的算法框架,而將一些步驟延遲到子類中,使得子類能夠不改變一個算法的結構便可重定義該算法的某些特定的步驟。
不用解釋太多,感受越解釋越糊塗,直接拿Android中的源碼來講事!
咱們知道,啓動一個Activity
過程很是複雜,若是讓開發者每次本身去調用啓動Activity過程無疑是一場噩夢。好在啓動Activity
大部分代碼時不一樣的,可是有不少地方須要開發者定製。也就是說,總體算法框架是相同的,可是將一些步驟延遲到子類中,好比Activity
的onCreate
、onStart
等等。這樣子類不用改變總體啓動Activity
過程便可重定義某些具體的操做了~。
定義:封裝一些做用於某種數據結構中各元素的操做,它能夠在不改變這個數據結構的前提下定義做用於這些元素的新的操做。
訪問者模式是23種設計模式中最複雜的一個,但他的使用率並不高,大部分狀況下,咱們不須要使用訪問者模式,少數特定的場景才須要。
Android中運用訪問者模式,其實主要是在編譯期註解中,編譯期註解核心原理依賴APT(Annotation Processing Tools),著名的開源庫好比ButterKnife、Dagger、Retrofit都是基於APT。APT的詳細使用這裏不提,後面我會寫關於APT相關的文章,敬請期待~
定義:中介者模式包裝了一系列對象相互做用的方式,使得這些對象沒必要相互明顯調用,從而使他們能夠輕鬆耦合。當某些對象之間的做用發生改變時,不會當即影響其餘的一些對象之間的做用保證這些做用能夠彼此獨立的變化,中介者模式將多對多的相互做用轉爲一對多的相互做用。
何時用中介者模式呢?其實,中介者對象是將系統從網狀結構轉爲以調停者爲中心的星型結構。
舉個簡單的例子,一臺電腦包括:CPU、內存、顯卡、IO設備。其實,要啓動一臺計算機,有了CPU和內存就夠了。固然,若是你須要鏈接顯示器顯示畫面,那就得加顯卡,若是你須要存儲數據,那就要IO設備,可是這並非最重要的,它們只是分割開來的普通零件而已,咱們須要同樣東西把這些零件整合起來,變成一個完總體,這個東西就是主板。主板就是起到中介者的做用,任何兩個模塊之間的通訊都會通過主板協調。
那麼Android中那些地方用到了中介者模式呢?在Binder
機制中,就用到了中介者模式,對Binder
不是很熟悉的童鞋請參考個人《 簡單明瞭,完全地理解Binder》。咱們知道系統啓動時,各類系統服務會向ServiceManager
提交註冊,即ServiceManager
持有各類系統服務的引用 ,當咱們須要獲取系統的Service
時,好比ActivityManager
、WindowManager
等(它們都是Binder
),首先是向ServiceManager
查詢指定標示符對應的Binder,再由ServiceManager
返回Binder
的引用。而且客戶端和服務端之間的通訊是經過Binder驅動來實現,這裏的ServiceManager
和Binder
驅動就是中介者。
定義:爲其餘類提供一種代理以控制這個對象的訪問。
其實代理模式咱們平時用的也比較多,其實比較好理解,就是當咱們須要對一個對象進行訪問時,咱們不直接對這個對象進行訪問,而是訪問這個類的代理類,代理類能幫咱們執行咱們想要的操做。代理模式比較容易理解,既然你來看這篇文章相信你對代理模式不陌生。
咱們直接看看代理模式在Android中的應用,若是你查看AIDL生成的代碼就知道,它會根據當前的線程判斷是否要跨進程訪問,若是不須要跨進程就直接返回實例,若是須要跨進程則返回一個代理,這個代理幹什麼事情呢?咱們在《 簡單明瞭,完全地理解Binder》提到,在跨進程通訊時,須要把參數寫入到Parcelable對象,而後再執行transact函數,咱們要寫的代碼挺多的。AIDL經過生成一個代理類,代理類中自動幫咱們寫好這些操做。
定義:將對象組成成樹形結構,以表示「部分-總體」的層次結構,使得用戶對單個對象和組合對象的使用具備一致性。
上面的定義不太好理解,咱們直接從Android中用到的組合模式提及。咱們知道,Android中View的結構是樹形結構,每一個ViewGroup包含一系列的View,而ViewGroup自己又是View。這是Android中很是典型的組合模式。
定義:把一個類的接口變換成客戶端所期待的另外一個接口,從而使本來因接口不匹配而沒法在一塊兒工做的兩個類可以在一塊兒工做。
其實適配器模式很容易理解,咱們在Android開發時也常常用到。比較典型的有ListView和RecyclerView。爲何ListView須要使用適配器呢?主要是,ListView只關心它的每一個ItemView,而不關心這個ItemView具體顯示的是什麼。而咱們的數據源存放的是要顯示的內容,它保存了每個ItemView要顯示的內容。ListView和數據源之間沒有任何關係,這時候,須要經過適配器,適配器提供getView方法給ListView使用,每次ListView只需提供位置信息給getView函數,而後getView函數根據位置信息向數據源獲取對應的數據,根據數據返回不一樣的View。
定義:動態的給一個對象添加額外的智者,就增長功能來講,裝飾模式比子類繼承的方式更靈活。
經過簡單代碼來理解裝飾模式:
public abstract class Component{ public abstract void operate(); } public class ConcreteComponent extends Component{ public void operate(){ //具體的實現 } } public class Decorator{ private Component component; public Decorator(Component component){ this.component=component; } public void operate(){ operateA(); component.operate(); operateB(); } public void operateA(){ //具體操做 } public void operateB(){ //具體操做 } }
那麼在Android哪裏出現了裝飾模式呢?咱們平時常常用到Context類,可是其實Context類只是個抽象類,具體實現是ContextImpl,那麼誰是ContextImpl的裝飾類呢?咱們知道Activity是個Context,可是Activity 並非繼承於Context,而是繼承於ContextThremeWrapper.而ContextThremeWrapper繼承於ContextWrapper,ContextWrapper繼承Context.說了這麼多,跟裝飾模式有啥關係?主要是引入ContextWrapper這個類。ContextWrapper內部有個Context引用mContext,而且ContextWrapper中對Context的每一個方法都有實現,在實現中調用的就是mContext相同的方法。
定義:使用享元對象有效地支持大量的細粒度對象。
享元模式咱們平時接觸真的不少,好比Java中的常量池,線程池等。主要是爲了重用對象。
在Android哪裏用到了享元模式呢?線程通訊中的Message,每次咱們獲取Message時調用Message.obtain()
其實就是從消息池中取出可重複使用的消息,避免產生大量的Message對象。
定義:要求一個子系統的外部與其內部的通訊必須經過一個統一的對象進行。
怎麼理解呢,舉個例子,咱們在啓動計算機時,只需按一下開關鍵,無需關係裏面的磁盤、內存、cpu、電源等等這些如何工做,咱們只關心他們幫我啓動好了就行。實際上,因爲裏面的線路太複雜,咱們也沒辦法去具體瞭解內部電路如何工做。主機提供惟一一個接口「開關鍵」給用戶就好。
那麼Android哪裏使用到了外觀模式呢?依然回到Context,Android內部有不少複雜的功能好比startActivty、sendBroadcast、bindService等等,這些功能內部的實現很是複雜,若是你看了源碼你就能感覺獲得,可是咱們無需關心它內部實現了什麼,咱們只關心它幫咱們啓動Activity,幫咱們發送了一條廣播,綁定了Activity等等就夠了。
定義:將抽象部分與實現部分分離,使他們獨立地進行變化。
其實就是,一個類存在兩個維度的變化,且這兩個維度都須要進行擴展。
在Android中橋接模式用的不少,舉個例子,對於一個View來講,它有兩個維度的變化,一個是它的描述好比Button、TextView等等他們是View的描述維度上的變化,另外一個維度就是將View真正繪製到屏幕上,這跟Display、HardwareLayer和Canvas有關。這兩個維度能夠當作是橋接模式的應用。
MVC
全稱爲Model-View-Controller,也就是模型-視圖-控制器。MVC結構以下圖所示:
在Android中對MVC的應用很經典,咱們的佈局文件如main.xml就是對應View層,本地的數據庫數據或者是網絡下載的數據就是對應Model層,而Activity對應Controller層。
MVP
MVP全稱爲Model View Presenter,目前MVP在Android應用開發中愈來愈重要了,它的結構圖以下:
它下降了View與Model之間的耦合。完全將View與Model分離。MVP不是一種標準化的模式,它由不少種實現。
MVVM
全稱是Mode View ViewModel,它的結構以下所示:
咱們在使用ListView時,會自定義一個ViewHolder,在RecyclerView中是必須使用ViewHolder,這主要是提升性能,由於不須要每次去調用findViewById來獲取View。其實ViewHolder就是個ViewModel。