編輯:關於Android編程
對編程稍稍深入了解一點的工程師來說,設計模式並不陌生。但設計模式的理解和運用每個層次的人有不同深度和廣度的理解。
接下來我就來講述一下我所理解的設計模式。
若有其他理解的工程師,歡迎前來探討!
若想了解設計模式,那麼就要先摸清它的原則和行為模式。
設計模式不針對哪種編程語言,而是針對編程思想。所以我把設計模式歸為內功心法之中。
先來說說設計模式的原則(包括標准原則描述和自己理解的描述)。
*對擴展開放,對修改關閉。
在程序需要進行拓展的時候,不能去修改原有的代碼,實現一個熱插拔的效果。
為了使程序的擴展性好,易於維護和升級。想要達到這樣的效果,我們需要使用接口和抽象類。*
開,對所有的拓展、細化、優化操作開發。
閉,對原有邏輯的修改關閉。
開閉原則的目的就是保證原有邏輯的正常情況下添加新的邏輯。
舉個栗子:一個工廠,開始做肥皂。後來為了拓展行業渠道,嘗試做香皂。那麼這個工廠就要遵守開閉原則。對新增做香皂的業務開放(新開一條生產鏈),對修改做肥皂的業務關閉(把肥皂嘗試做成香皂)。要不然,香皂做不成,把肥皂也修改的不能正常盈利,豈不是搬石頭砸了自己的腳。
*它是面向對象設計的基本原則之一。
任何父類或者基類可以出現的地方,子類一定可以出現。
它是繼承復用的基石。只有當衍生類可以替換掉基類,軟件單位的功能不受到影響時,基類才能真正被復用,而衍生類也能夠在基類的基礎上增加新的行為。
裡氏代換原則是對“開-閉”原則的補充。
實現“開-閉”原則的關鍵步驟就是抽象化。
而基類與子類的繼承關系就是抽象化的具體實現,所以裡氏代換原則是對實現抽象化的具體步驟的規范*
裡氏代換的原則很簡單,就是一個兒子,你如果想去做你父親做的事情,那麼你必須學會你父親會的所有技能。作為兒子,你可以去編程,會武術,學跳舞。但是前提是你父親會的喝酒,抽煙,把妹你都要會。這樣,作為兒子才能真正的接替父親的位置。
程序中,任何一個父類或者基類的方法在其子類或者孫子類中都必須全部繼承或者全部實現。這樣當任何一個需要基類的地方都可以用其子類代替。這就是裡氏代換的原則。
這個是開閉原則的基礎,具體內容:針對接口編程,依賴於抽象而不依賴於具體。
這個空口說來也說不太清楚,還是舉個栗子:一個機器要把很多種類的飲料分類,最笨的辦法就是給機器輸入命令“碳酸飲料:可樂,雪碧,芬達;牛奶類:蒙牛,光明,伊利。”這樣,機器就會去一一對應的找飲料,找到了可樂,就把它丟在碳酸飲料類。這叫讓機器依賴“具體”。讓它知道什麼是什麼。
而依賴抽象,則是弄出很多的大盒子,每個盒子上都是標簽,比如碳酸飲料,牛奶,咖啡什麼的。
機器只需要將每個盒子那來歸類。碳酸飲料的盒子就放在碳酸飲料類裡面。這樣,機器不用知道每種飲料是什麼,機器只用知道面前的幾個大盒子是什麼該放在哪裡就ok。盒子就是“抽象”的。盒子可以代表可樂,可以代表雪碧,可以代表芬達。所以,盒子就成了邏輯(機器)和具體(飲料)之間的抽象(盒子)了。
這樣看來,的確減少了很多的工作量。
使用多個隔離的接口,比使用單個接口要好。還是一個降低類之間的耦合度的意思。
標准解釋還是不太清楚。我補充一下:接口隔離的意思是:不要一個類放一個他自己需要的接口,然後其他類去調用這個類的時候去使用這個接口。而是把所有的接口統一起來,這個類需要實現某個接口,直接調用接口類中的接口。另一個類需要使用某個接口,則就實例化接口類中的某個接口。
這就是把接口隔離在一個類中統一管理。讓類與類之間沒有聯系,而讓他們都去找接口。
現實中有個東西就很好的表明這一思想。活動扳手。扳手的卡口是可以活動的。就像把很多型號的卡口集中於一身。這樣,不管是那個螺絲都能來找這個扳手,找到自己想要的卡口型號。這個扳手的卡口就相當於一個“接口”的統一管理類。而螺絲就是很多很多需要某個接口的“使用類”。而扳手則就是某個型號的“實現類”。卡口就成功的成了隔離眾多接口的一個“接口統一管理類”
為什麼叫最少知道原則,就是說:一個實體應當盡量少的與其他實體之間發生相互作用,使得系統功能模塊相對獨立。
這個比較容易理解。程序中,最少知道原則的最好體現就是眾多的utils工具類。某個工具類,你傳入一個參數,就可以返回給你一個想要的結果。這就是最少知道原則的最好體現。當然,放在設計模式中比這個要稍微復雜一些,不過意思就是這樣。
*原則是盡量使用合成/聚合的方式,而不是使用繼承。
組合和聚合都是對象建模中關聯(Association)關系的一種.聚合表示整體與部分的關系,表示“含有”,整體由部分組合而成,部分可以脫離整體作為一個獨立的個體存在。組合則是一種更強的聚合,部分組成整體,而且不可分割,部分不能脫離整體而單獨存在。在合成關系中,部分和整體的生命周期一樣,組合的新的對象完全支配其組成部分,包括他們的創建和銷毀。一個合成關系中成分對象是不能與另外一個合成關系共享。*
這個理解起來用兩個集體來表示最好不過。聚合就相當於一個班級。6年3班由40個同學組成,某個同學走了,6年3班還是6年3班,走的同學還是可以完成作為學生的一切行為。就算走了39個同學,意思還是一樣。聚合由個體組成,但個體可以脫離聚合單獨使用,聚合失去個體也可以存在。
而組合就相當於一個app軟件開發團隊。隊伍中有銷售,有後台,有android,有ios,還有經理。這是一個團隊,是個“合成”。這個組合中任何一個成員離開都不能叫團隊了,而離開的成員也不能單獨完成任務。開發團隊就是一個部分組成但不可分割的“合成”。
不管是聚合還是合成,其中的對象都不能和另外的聚合或者合成達成關系。就像,6年3班的同學不可能是6年4班的同學,這個開發團隊的成員不可能同時為另一個團隊工作。
好了,這就是設計模式的原則。只要深入了解了設計模式的原則, 自己就可以設計出很多優秀的設計模式。現在為止設計模式已經有很多種了,但是最經典的還是人人熟知的那24種。
那麼,個人建議每一種都要學習,一一學習的機會就留給大家去完成了。我主要說說,android中經常用到的一些設計模式。
一般來說,常用的有以下八種:單例、工廠、觀察者、代理、命令、適配器、合成、訪問者。
單例模式:目的是為了讓系統中只有一個調用對象,缺點是單例使其他程序過分依賴它,而且不同單例運行在不同進程中,使得維護困難;
這裡不得不提到一點,一般的單例,剛剛開始接觸設計模式的人會用synchronized來同步不同線程中的進入順序。
雖然很直觀很簡單。但是,這種單例在序列化和反射機制的時候依然不能達到單例的效果。也就是說它能滿足百分之九十的邏輯處理。只要你的程序不太復雜,那麼用這種是完全沒問題的。
那麼問題來了。還有沒有更好的辦法?
其實早就不是什麼新技巧了。枚舉。
由於時間原因,以後會詳細講解。
工廠模式:生產固定的一些東西,如抽象類,缺點是產品修改麻煩;如喜歡動作片和愛情片的人分別向服務器發出同一個請求,就可以得到他們想看的影片集,相當於不同對象進行同一請求,需求均得到滿足。
做過類似超市收銀的應該都清楚,工廠模式在其中體現的最為貼切。最好是工廠+策略模式,同時使用。
觀察者模式:就是多個對象對一個對象進行監控,如緩存;
觀察者模式讓我想起了一個小小的工具庫“EventBus.jar”。
這個工具庫就是規定方法名,發送請求後,所有被規定的方法名的方法都會接收到值,就相當於一個比較簡化的觀察者模式。
我在設計框架的時候經常用這個工具庫去發送網絡請求的返回值。因為網絡請求在任何頁面任何時候都要返回。所以觀察者模式再適合不過了。
代理模式:自己的事交給別人去做,分別返回結果即可,如異步線程;
命令模式:調用對象與作用對象之間分離,由中間件來協調兩者之間的工作,如控制器;
適配器模式:將一個接口變成用戶所需要的接口,如baseadapter可以適配listview和spinner,因為它們有相同的接口
合成模式:將一對多的關系轉換成一對整體的關系,如listview與適配器;
訪問者模式:對不同的對象采取不同的處理,如instanceof。
由於今天時間關系,先把這篇文章的目的寫出來。 詳解了設計模式的原則和幾種android中常用的設計模式。 後續會給出每種設計模式的詳細解釋。
在前面我們在解決線程同步問題的時候使用了synchronized關鍵字,今天我們來看看Java 5.0以後提供的線程鎖Lock.Lock接口的實現類提供了比使用synch
程序運行效果圖: 程序代碼: /** * 獲取所有軟件信息 * 1.通過異步的方式顯示系統中所有軟件 * 2.單擊打開指定軟件 * 3.將所有軟件的包名
最近項目上用到了卡片的翻轉效果,大致研究了下,也參考了網上的一些Demo,簡單實現如下:activity_main.xml<?xml version=1.0
相信去年聖誕節打開過手機淘寶的童鞋都會對當時的特效記憶猶新吧:全屏飄雪,旁邊還有個小雪人來控制八音盒背景音樂的播放,讓人有種身臨其境的感覺,甚至忍不住想狠狠購物了呢(誤)