單例模式
Builder
原型模式
工廠方法
抽象工廠java
策略模式
狀態模式node
觀察者模式
中介者模式
訪問者模式
迭代器模式
模板方法算法
備忘錄模式
命令模式
解釋器模式
職責鏈模式數據庫
組合模式
代理模式
裝飾模式
外觀模式設計模式
享元模式
橋接模式
適配器模式安全
談到設計模式,不得不說說面向對象的六大原則網絡
單一原則通俗的講就是一個類只表達一個概念、一個方法只作一件事情。將一組相關性很高的函數、數據封裝到一個類中。換句話說,一個類應該有職責單一。數據結構
開閉原則就是一個類對於擴展是開發的,可是對於修改是封閉的。這也是六大原則中最難的,一般開閉都是短暫的美好,但在業務升級與拓展的狀態下,原理的開閉是沒法知足。即便是這樣,也要儘量的擴展而不是修改。多線程
全部引用基類的地方必須能透明地使用其子類對象。看着定義非常抽象,可是通俗的理解就是由子類實例化的父類引用,在使用這個引用時,感受就像是使用了父類同樣。一個簡單的例子:併發
public class T{ private class A{...} class B extends A{...} public static void main(String[] args){ A a = new B(); // 類型是A,但實際是B類型實例化的 a.method(); } }
依賴倒置主要是爲了解耦。具體來講:
類之間的依賴關係應該創建在最小的接口上其原則是將繁雜的功能接口拆分紅更加單一職責的接口,防止接口內部的耦合。
一個對象應該對其餘的對象有最少的瞭解 保留關鍵的共有方法,其餘次要的都是私有方法,不該該被外部瞭解。
定義:確保單例類只有一個實例,而且這個單例類提供一個函數接口讓其餘類獲取到這個惟一的實例。
單例模式的意義是顯而易見的,能極大的節省資源,提升代碼運行效率。缺點也是很明確的,就是不能發生狀態的變化,以提供統一的功能。
單例模式有懶漢式與餓漢式,實現方式有靜態成員變量法、枚舉法、容器法等。單例須要注意的就是懶漢模式下的多線程安全問題。這裏給出懶漢模式比較優雅的實現代碼,其原理就是類加載器ClassLoader保證了併發的安全性。
public class Singleton{ private Singleton(){} public static synchronized Singleton getInstance() { return SingletonHolder.instance; } private static class SingletonHolder{ private static final Singleton instance = new Singleton(); } }
Android系統下的單例模式有
//獲取WindowManager服務引用 WindowManager wm = (WindowManager)getSystemService(getApplication().WINDOW_SERVICE);
定義:將一個複雜對象的構造與它的表示分離,使得一樣的構造過程能夠建立不一樣的表示。
AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setIcon(R.drawable.icon) .setTitle("title") .setMessage("message") .setPositiveButton("OK", null) // create以前的set方法操做的都是AlertDialog.Builder而已 .create() // create以後就建立出一個真實的AlertDialog了,將複雜的建立過程都隱藏在create方法內部 .show();
從上述代碼中能夠很是直觀的看出Builder模式就是先設置好各類參數,而後再經過一個方法的調用構建出來一個複雜的對象。
原型模式很簡單,使用一個實例拷貝後的實例。
在java中拷貝存在深拷貝與淺拷貝,若是類中的成員變量都是基本數據類型,則系統自動實現這些基本數據類型的深拷貝。
那什麼時候要用到原型模式呢?防止本身的實例在傳入別的模塊後,發生意外的修改。進行一次拷貝,再將該實例當作參數傳遞給別人,是很是明智的操做,尤爲是這個實例是某個類的成員變量。
Uri uri = Uri.parse("smsto:10086"); Intent shareIntent = new Intent(Intent.ACTION_SENDTO, uri); // 這裏舉例說明intent是提供了一次clone方法的 Intent intent = shareIntent.clone(); // 假設startActivity方法會修改intent startActivity(intent); // 而後接着使用shareIntent進行其餘操做 // 若是不clone,鬼知道shareIntent會變成什麼樣子 shareIntent.putExtra("key", "extra") ...
定義:定義一個建立對象的接口,讓子類決定實例化哪一個類
public abstract class Product{ public abstract void method(); } public abstract class Factory{ public abstract Product createProduct(); } 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 class MyFactory extends Factory{ public Product createProduct(){ return new ConcreteProductA(); } }
Android下的例子有BitmapFactory
public class BitmapFactory { public static Bitmap decodeFile(String pathName, Options opts) { Bitmap bm = null; ...... return bm; } }
定義:爲建立一組相關或者是相互依賴的對象提供一個接口,而不須要制定他們的具體類
public abstract class AbstractProductA{ public abstract void method(); } public abstract class AbstractProdectB{ public abstract void method(); } // 這個工廠一旦建立,就天生必須擁有兩條生產線,具體生產什麼,將由子類決定 public abstract class AbstractFactory{ public abstract AbstractProductA createProductA(); public abstract AbstractProductB createProductB(); } 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 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();} }
抽象工廠與工廠方法的區別,表面上看就是生產線是多條,仍是有一條。但其設計模式的思想是表達了抽象工廠表示一組關聯的生產線,而不只僅是表示同一類型的生產線。
這並非一個真正的模式,可是和抽象工廠和工廠方法模式同樣,它常常被用於封裝建立對象的代碼
// 根據傳入的參數決定給出哪一個Service 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 AbstractSortAlgorithm { public abstract sort(List list); } public class CustomList extends List { private AbstractSortAlgorithm algorithm; public void setSortAlgorithm(AbstractSortAlgorithm algorithm){this.algorithm = algorithm;} public void sortList() {algorithm.sort(this);} }
Android的屬性動畫中使用時間插值器,就是策略模式。
容許對象在內部狀態改變時改變它的行爲,對象看起來好像修改了它的類。
public abstract class Actor { public abstract void act(); } class GirlActor extends Actor{ public void act(){System.out.println("GirlActor");} } class BoyActor extends Actor{ public void act(){System.out.println("BoyActor");} } class Stage{ private Actor actor; public void firstFrame(Actor actor){this.actor = new GirlActor();} public void secondFrame(Actor actor){this.actor = new BoyActor();} // 在不一樣的狀態下會有不一樣的輸出 public void performPlay(){ actor.act(); } }
狀態模式在Android下使用的仍是不少的,好比WIFI在開啓時,自動掃描周圍的接入點,而後以列表展現,當WIFI關閉時,清空列表。
定義:使多個對象都有機會處理請求,從而避免請求的發送者和接收者直接的耦合關係,將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有對象處理它爲止。
最好的一個例子就是View的測量,定位,繪製,事件傳遞,事件分發等。這些例子都是從父View開始依次向子View進行,是一個特別典型的責任鏈模式。特別要提到的是,savedInstance的處理也是責任鏈模式。
定義:給定一個語言,定義它的語法,並定義個解釋器,這個解釋器用於解析語言。
通俗的來說,就是自定義一個格式文件,而後解析它。
AndroidManifest.xml是典型的一個自定義xml文件語言,layout目錄下的xml文件,都是具備特殊語法的文件。他們都會被XmlPullParser這個解析器進行解釋。
定義:命令模式將每一個請求封裝成一個對象,從而讓用戶使用不一樣的請求把客戶端參數化;將請求進行排隊或者記錄請求日誌,以及支持可撤銷操做。
在Android底層的事件機制中,底層邏輯對事件的轉發處理。每次的按鍵事件會被封裝成NotifyKeyArgs對象,經過InputDispatcher封裝具體的事件操做。
定義:定義了對象之間的一對多的關係,其實就是1:n,當「1」發生變化時,「n」所有獲得通知,並更新。
觀察者模式比較典型的場景就是發佈消息通知訂閱者。沒錯Android下的廣播就是觀察者模式,在FrameWork層,狀態發生變化後(好比WIFI狀態),會遍歷所有的register。
定義:在不破壞封閉的前提下,捕獲一個對象的內部狀態,並在對象以外保存這個狀態,這樣,之後就能夠將對象恢復到原先保存的狀態中。
通俗的講就是一個提早備份,一旦出現問題,能儘量的恢復到最接近以前的狀態。
Android下的onSaveInstanceState就在時不時的進行着備忘,在onRestoreInstanceState時,就能取出最後的記錄。
定義:提供一種方法順序訪問一個容器對象中的各個元素,而不須要暴露該對象的內部表示。
這個迭代器再好理解不過了,咱們每天用的Iterator正是這種迭代器模式。
在Android中SQLiteDatabase的query也是迭代器模式
cursor = database.query(...);
while(cursor.moveToNext()){ cursor.get...; }
定義:定義一個操做中的算法框架,而將一些步驟延遲到子類中,使得子類能夠不改變一個算法的結構便可重定義該算法的某些特定的步驟。
直接看代碼
public class CustomActivity extends Activity { // Activity留給用戶自定義某些特定步驟 protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); // ... ... } }
能夠看出模板方法就是留出適當的方法等待子類來實現。無論如何重寫父類,父類的主邏輯將不會被改變。
定義:封裝一些做用於某些數據結構中各元素的操做,它能夠在不改變這個數據的前提下定義做用於這些元素的新的操做。
Android中不多使用訪問者模式,ButterKnife中到是使用了。
這裏只給出一個案例:
場景:一羣人到你家,一塊兒餵食寵物
下面就具體來看實現:
interface Animal { void accept(Person person); }
interface Person { void feed(Cat cat); void feed(Dog dog); }
class Dog implements Animal { @Override public void accept(Person person){ person.feed(this); System.out.println("旺旺"); } } class Cat implements Animal { @Override public void accept(Person person){ person.feed(this); System.out.println("喵喵"); } }
class Owner implements Person { @Override public void feed(Cat cat) {System.out.println("主人餵食貓");} @Override public void feed(Dog dog) {System.out.println("主人餵食狗");} } class Someone implements Person { @Override public void feed(Cat cat) {System.out.println("客人餵食貓");} @Override public void feed(Dog dog) {System.out.println("客人餵食狗");} }
class Home { private List<Animal> nodeList = new ArrayList<>(); void add(Animal animal) {nodeList.add(animal);} void action(Person person) { for (Animal node : nodeList) {node.accept(person);} } }
public class Test { public static void main(String[] args) { Home home = new Home(); home.add(new Dog()); home.add(new Cat()); Owner owner = new Owner(); home.action(owner); Someone someone = new Someone(); home.action(someone); } }
定義:中介者模式包裝了一系列對象相互做用的方式,使得這些對象不
必相互明顯調用,從而使他們能夠輕鬆解耦。當某些對象之間的做用發生改變時,不會當即影響其餘的一些對象之間的做用,保證這些做用能夠彼此獨立的變化,中介者模式將多對多的相互做用轉爲一對多的相互做用。
中介者相似於電腦主板,主板接着顯示器,硬盤鍵盤等等設備,設備之間的通訊所有通過主板協調。
在Android中的Binder驅動也是一箇中介者,全部的Service在通訊以前都會向ServiceManger查詢出目標Service,也就是說,進程直接不是直接跨進程,而是由ServiceManager來管理的。因此說Binder啓動就是一箇中介者模式。
定義:爲其餘類提供一種代理以控制這個對象的訪問。
AIDL文件會生成一個代理類,在跨進程通訊傳遞數據時,Parcelable對象的序列化與transct寫入對方進程的內存地址,這一系列的操做都被代理類進行了隱藏。因此代理模式能很好的隱藏一些複雜的操做。
定義:將對象組成樹形結構,以表示「部分-總體」的層次結構,使得用戶對單個對象和組合對象的使用具備一致性。
Android中的ViewGroup即是樹形結構,每一個ViewGroup包含一系列View,而ViewGroup自己就是View。這即是組合模式。
定義:把一個類的接口變換成客戶端所期待的另外一個接口,從而使本來因接口不匹配而沒法在一塊兒工做的兩個類可以在一塊兒工做。
適配器使用的頻率特別高,每一個ListView和RecycleView都須要適配器來給出每一個ItemView。至於如何給出ItemView,可能不盡相同,可是Adapter給出了一個統一的接口規範,只須要進行一次轉換便可。
定義:動態的給一個對象添加額外的指責。就增長功能來講,裝飾模式比子類集成的方式更靈活。
Android中的ContextWrapper(ContextThemeWrapper的父類(Acrtivity的父類))。是一個地地道道的裝飾者
public class ContextWrapper extends Context { Context mBase; // 由構造函數傳入一個content public ContextWrapper(Context base) { mBase = base; } }
定義:使用享元對象有效地支持大量的細粒度對象。
享元能夠說一直都在被使用,好比Java的常量池,線程池等。主要是爲了重用對象。
在Android中,Handler機制中有個postMessage方法,能夠經過Message.obtain()來從消息池中取出可複用Message,避免產生大量Message對象。
定義:要求一個子系統的外部與其內部的通訊必須經過一個統一的對象進行。
外觀模式核心在於子系統與外部通訊,好比當你sendBroadcast、startActivity、bindService等等,系統內部的實現很是複雜,可是一個統一的對象context把子系統所有隱藏起來。
定義:將抽象部分與實現部分分離,使他們獨立地進行變化。
一個類在多個維度上要進行變化,好比列表View在列表如何展現與數據來源上的兩個維度的變化。具體來講就是AbsListView的兩個維度的變化,AbsListView的子類有ListView、GridView、CustomListView等等,而ListAdapter也是一個變化的維度。
全稱是Model-View-Controller,以下圖:
在Android下,layout.xml就是View層。數據層能夠由數據庫與網絡數據構成Model,但Model層要徹底表達數據的輸入與輸出。Activity就是Controller層,在比較複雜的Activity中,每每不能很好的完成表達成Controller層,每每混合了View層代碼與Model層代碼,這也是Activity的尷尬之處。
Model-View-Presenter,以下圖:
這個模式主要是爲了解決Activity在MVC模式下的尷尬處境,把Activity徹底表示爲一個View層。這樣Activity就能夠很單純的處理View的問題了,處理View顯示問題也是Activity的特長。
Model-View-ViewModel,以下圖:
這個模式優化的顯示層的問題,View單向的訪問ViewModel,ViewModel與Model之間進行交互。在RecycleView中的ViewHolder正是這種模式。