Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Aandroid開發中的設計模式實踐(一)

Aandroid開發中的設計模式實踐(一)

編輯:關於Android編程

以文本和思維導圖的方式簡明扼要的介紹了GoF的23個經典設計模式,可當成學習設計模式的一個小手冊,偶爾看一下,說不定會對大師的思想精髓有新的領悟。 GoF(“四人幫”,又稱Gang of Four,即Erich Gamma, Richard Helm, Ralph Johnson & John Vlissides) 設計模式是在軟件開發過程中,對於一些普適需求總結的設計模板。根據目的可以分為三類: (1).創建型:與對象的創建相關。 (2).結構型:處理類或者是對象的組合。 (3).行為型:對類或者對象怎麼進行交互,怎樣分配職責進行描述。 需要注意:設計模式只是提供一種思路,能夠直接套用的情況不多,更多的是處理問題的思路。 \   面向對象的六大原則: (1)單一職責原則:就一個類而言,應該僅有一個引起它變化的原因。關鍵是職責劃分 (2)開閉原則:軟件中的對象(類·模塊·函數)應該對擴展是開放的,對於修改是封閉的。關鍵是通過抽象實現。 (3)裡式替換原則:所以引用基類的地方必須能透明的使用其子類替換。依賴繼承與多態特性。 (4)依賴倒置原則:模塊間的依賴通過抽象發生,實現類之間不發生直接的依賴關系,其依賴關系通過接口或抽象類產生的。 (5)接口隔離原則:客戶端不應該依賴它不需要的接口。類間的依賴關系應該建立在最小的接口上。接口隔離原則將非常龐大,臃腫的接口拆分成更小的和更具體的接口,這樣客戶端只需要關注他們感興趣的方法。 (6)迪米特原則【最少知識原則】:一個對象應該對其他對象有最少的了解。一個類應該最自己需要耦合或調用的類知道的最少,類的內部如何實現與調用者或依賴者沒關系,調用者或者依賴者只需要知道它需要的方法即可。   1.單例模式-應用最廣的模式 定義:確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例。 實現單例模式主要有以下幾個關鍵點: (1)構造函數不對外開放,一般為private。 (2)通過一個靜態方法或者枚舉返回單例類對象。 (3)確保單例類的對象有且只有一個,特別是在多線程環境下。 (4)確保單例類對象在反序列化時不會重新構建對象。   實現方式: (1)餓漢模式:默認初始化一個自身的靜態對象,對外的靜態方法每次返回該實例。 (2)懶漢模式:靜態方法加同步鎖,第一次調用時,如果該實例為空,才會構造。每次調用都同步,造成不必要開銷。 (3)Double Check Lock(DCL)雙重檢查鎖定。
if(mInstance==null){
synchronized(Instance.class){
if(mInstance==null){
mInstance=new Instance();
}
}
}
這個關鍵在與進行了2此mInstance判空,加了類同步鎖。由於java編譯器允許處理器亂序執行。因此在1.6以下或者並發場景比較復雜時不推薦。這是我們平時用的最多的一種方式。 (4)靜態內部類單例模式: 這種方式只在第一次調用靜態方法時,才會導致其靜態內部類加載到虛擬機,初始化對象。不僅能夠保證線程安全,也能夠保證單例對象的唯一性,同時延遲了單例的實例化,所以是推薦使用的實現方式。 (5)枚舉單例:枚舉實例的創建時線程安全的,並且在任何情況下都是一個單例 (6)使用容器實現單例模式:將多種單例類型注入到統一管理器中,根據key獲取。   序列化相關: 通過序列化可以將一個單例的實例對象寫到磁盤,然後讀回來,從而有效獲得一個實例。 即使構造函數是私有的,反序列化依然尅通過特殊的途徑去創建類的一個實例,相當於調用該類的構造函數。 反序列化操作提供了一個很特別的鉤子函數,類中具有一個私有,被實例化得方法readResolve(),這個方法可以讓開發人員控制對象的反序列化。 要杜絕單例被反序列化重新生成對象,必須加入如下方法:
private Object readResolve() throws ObjectStreamException{
return mInstance;
}
  也就是在readResolve方法中將,mInstance返回,而不是默認重新生成一個對象。枚舉不存在這個問題。   優點: (1)單例模式在內存中只有一個實例,減少內存開支,特別一個對象模塊需要頻繁創建銷毀,而創建銷毀時性能又無法優化,單例模式就非常有用。 (2)單例模式可以在系統設置全局的訪問點,優化和共享資源訪問。 (3)利用單例模式可以避免對資源的多重占用,解決線程安全,統一解決訪問問題 缺點: (1)單例模式沒有接口,擴展困難。只能修改源碼。 (2)單例對象如果持有context容易引發內存洩漏,此時需要注意傳遞給單例對象的context最好是Application的context。   2.建造者模式-Builder 定義:將一個復雜對象的構建和表示分離,使得同樣的構造過程創建不同的表示結果。 使用:實際開發中,我們一般是直接使用一個builder來進行對象的組裝,裡面全部是構造或者表示的參數,我們可以設置鏈式調用,關鍵點是每個setter方法返回自身,return this;這樣就可以鏈式調用。 AlertDialog.Builder的實現,就是為了構建復雜的AlertDialog,將dialog的構造和表示分開。 這個的使用,在開源項目中比較常見,比如Universal image loader中,通過將ImageLoaderConfig的構造函數,字段私有化,使得外部不能訪問內部屬性,用戶只能通過設計Builder對象的屬性,通過Builder構造出ImageLoaderConfig對象,這樣就實現構造和表示的分離。   通過配置類的構造器Builder將配置的構造和表示分離開來,同時又將配置從目標類中隔離處理,避免過多的setter方法污染目標類。以及方便的鏈式調用。   優點: (1)良好封裝性,使用建造者模式可以是客戶端不必知道產品內部組成的細節。 (2)構造者獨立,容易擴展。 缺點: 產生多余的Builder對象,消耗內存。   3.原型模式-使程序運行更高效 定義:用原型實例,指定創建對象的種類,並通過拷貝這些原型創建新的對象。 使用場景: (1)類初始化需要消耗非常多的資源,這個資源包括數據,硬件資源等,通過原型靠包避免這些消耗。 (2)通過new產生一個對象需要非常繁瑣的數據准備或者訪問權限,這是可以使用原型模式。 (3)一個對象需要提供給其他對象訪問,而且各個調用者可能讀需要修改其值時,可以考慮使用使用原型模式拷貝多個對象供調用者使用,即保護性拷貝。 注意: (1)通過實行Cloneable接口的原型模式在調用clone函數構造實例時並不一定比new操作更快,只有當通過new構造對象較為耗時或者成本較高時,才能獲得效率提升。 (2)clone()方法並不是Cloneable接口中的,而是Object中的方法,,Cloneable是一個標識接口,它表明這個類的對象是可拷貝的,如果沒有實現Cloneable接口,但是調用了clone()函數將拋出異常。所以我們一般的都是實現Cloneable接口,覆些clone()方法實現對象的拷貝實現,來實現原型模式。 (3)通過clone拷貝對象時不會執行構造函數。在使用Cloneable實現拷貝的時候,是調用了clone()方法實現,對象的構造韓式是不會執行的。如果構造函數中需要一些特殊初始化,可能發生問題。 (4)深拷貝與淺拷貝:區別在於拷貝對象時,深拷貝對引用型的字段同樣采用拷貝的方法。淺拷貝只是單純拷貝引用的形式。對於引用類型的,如果只是拷貝應用,那麼調用者會連原型對象的值一起改變,因為他們引用的最終指針地址是一處。而深拷貝,引用類型的會有新地址內存。   intent就是原型模式。
public Object clone(){
return new Intent(this);
}
只不過它是new比clone效率高,所以內部這麼實現。 比如平時應用比較多的,應該是保護性拷貝。 比如訂單提交界面,服務器接口,要求在提交的數據裡進行一些特定操作,會修改訂單數據。但是修改了這些數據在本地顯示就會有一些問題,或者上一次提交網絡異常,重新提交是原型數據發生了改變。 這種情況,我們就應該講本地初始數據,當作原型,深拷貝對象給其他調用者去處理,對應流程,那麼流程異常後,回退,原型數據是不變的,我們可以繼續對原型數據修改,後繼續提交等其他處理操作。   優點: 原型模式是在內存中二進制流的拷貝,要比直接new一個對象性能好很多,特別是在一個循環體內產生大量對象時,原型模式可以更好的體現其優點。 缺點: 直接在內存中執行,構造函數不會執行,實際開發中要注意這一點。   4工廠方法模式-應用最廣泛的模式
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved