上篇隨筆隨(Android 設計隨便說說)便說了一下什么是設計以及設計的原則,這里舉一個簡單的例子來進一步的說Android設計。我們以應用商店的設計來舉例。
在設計之前,需要把握兩部分內容,才能使得設計更加的合理,恰當。
第一部分是應用本身包含的業務都有哪些。應用商店的業務大體上有一下幾個:
1 給用戶展示apk信息
2 提供用戶下載apk
當然了已上還可以繼續細分。但是對於我們的例子來說已經足夠了。
第二部分本地sdk,也就是手機能夠提供哪些接口。對於上面的分析我們需要了解一下API。
第一,界面展示的API能否支持。
第二,網絡是否支持socket,
假設我們已經熟悉了應用商店的基本業務和需要的API,現在就開始我們的設計之旅。
在上一篇我提到了兩個較為關鍵着手點。一是模塊划分,二是合理組合。
說模塊划分之前需要說明的是什么是依賴,什么是接口。
所謂的依賴,就是模塊對外界類的調用的方法。所謂的依賴倒置是原來模塊對外界的依賴是實現,現在模塊對外界的依賴是虛接口。如果外界實體可以實現需實現虛接口,才可以和模塊實現依賴。
所謂的接口,就是模塊對外界提供的調用的方法。有兩種,一種是直接的一個public方法。一種是以接口的形式,告訴外界。
我們先說應用商店的模塊划分。
首先需要UI部分,UI的作用是什么?UI的作用有兩個,一是給使用者展現信息,二是提供給使用者一個操作的平台。因此UI部分需要數據,而這些數據的來源需要其他模塊的支撐,除非是一個helloworld程序。當然了在UI進程中不能做耗時操作,否則出現ANR。因此不允許在UI中網絡請求。
例舉一個頁面RecommendActivity,apk推薦頁面。
RecommendActivity(實體類,用戶用戶操作)對外的接口是
- apk詳情查看gotoAppDetailsInfo(id);調用這個方法實現apk詳情的展現。
- apk下載請求gotoDownLoadApp(id);調用這個方法實現apk的下載。
和接口類RecommendInterface(Interface,底層數據改變更新到界面)
- onPageViewDataComplate() 頁面你數據的回調
- onAppInfoDataComplate() appinfo數據的回調
- onImageComplate(uil)頁面圖片數據的回調
..............
RecommendActivity依賴是RecommendBase(Interface或虛基類,用於實現類的繼承)
- getPageViewData()獲取頁面的要顯示的模板信息。
- getAppInfosData()獲取要顯示頁面的app信息。
- getImages(appid)根據appid獲取頁面圖片信息
- setCommondInterface(RecommendInterface) 設置回調
..............
第二部分,網絡請求模塊。負責從服務端獲取APK數據。
NetTaskManager(實體類)網絡任務管理,這一模塊的接口類。它依賴於HttpGet,HttpConnect等網絡接口實現業務,已經是底層,依賴API即可。那么他提供的接口有哪些。
- downLoadImageByUrl()圖片加載接口
- downLoadTemplatesById(id)根據頁面編號請求模板
- downLoadAppsByTemplates()根據模板編號請求app數據。
- downLoadAppsInfo(id)根據id獲取app詳情
................
上面都是正向接口,但是它還需要將請求結果上報,由因為該模塊的實現是異步完成的,因此還需要定義一個回調NetTaskResultListener(接口)提供以下接口
- netTaskImageDownLoadCommplate(url),對外回報圖片已經下載完成。
- netTaskTemplatesDownLoadCommplate(id),對外回報模板數據已經下載完成
- netTaskAppsDownLoadComplate(id)對外回報app數據已經下載完成。
- netTaskAppsInfoComplate(id)對外回報app詳情數據
............
以上籠統的說了一下提供的接口。當然了還有一些細節這里不再計較。
第三部分,數據解析模塊,從網絡中來的數據流畢竟不能夠直接使用,需要一個轉換,這個模塊就負責這個任務。
舉例DataWorkManager(實體類) 負責數據的解析和組裝。
它依賴的接口,實際上他需要對數據解析,是json或是xml都是依賴於API,因此它的依賴是API。
它提供的接口如下:
- setData(temp, apps)負責將temp數據和apps數據解析和整合。(看起來好復雜啊,但是一般都是模板和apps數據對應的,所以無法分割出去)
- setIamge(url)當圖片下載完成,負責將圖片和界面關聯。
- setAppInfo(appinfos)負責appinfo數據的解析和模板整合。
......
此外,這些數據的處理要看數據量是否大,耗時是否會長。如果,數據量不大,而且耗時不長,則同步即可,不需要提供回調。
- getViewDataByTempId(); 獲取界面上要顯示的viewData。
- getIamgeByUrl(url);根據圖的url獲取圖。
- getAppsInfoData(id)根據appid獲取app詳情頁面數據
.......
如果運算量較大,耗時長,則需要異步處理,需要提供一個回調接口。這里不再細說。
第四部分,下載模塊,負責應用的下載。有人會問,下載也是從網絡中請求數據,為什么不在網絡請求模塊中。原因是這兩個模塊功能完全不同,網絡請求模塊的職責是負責頁面數據展示,隨着頁面的向下滑動,它需要同時不停的請求,如果頁面跳轉,則需要暫停原來的請求,進行新的請求。不確定性比較大。但是下載模塊,職責是負責apk的下載。他需要區分網絡是那種網絡,而且下載是按照順序的,除非人為改動。
例舉DownLoadAppManager(實體接口類)對於外界的依賴,實際上還是網絡接口的API。
對於外界的接口:
- startDownLoad();
- setDownLoadApps(appinfo);
............
此外對外還有一個回調接口類DownLoadListener
- downLaodProgress(id, progress);
.............
第五部分,調度模塊,為了上面的四個模塊有條不紊的實現業務,需要這個模塊進行調度。這個模塊是負責用戶交互和業務實現的中間模塊,對上層,負責接收用戶的響應和提供UI界面數據。對下層,負責調度各個業務單元實現整體業務。
以Controller來命名該模塊。
它需要提供的接口如下:
- getViewByTemp(id)用戶到不同的頁面啟動不同頁面上的數據請求。
- downLoad(id),stopDownload(id).....用戶下載的指令接口
- getAppInfo()用戶查看app詳情界面,啟動app詳情數據請求。
它還需要提供回調接口如下:
ControllerUIInterface
- onViewComplate(viewData);頁面數據組合完畢回調
- onDownloadProgress(id,progress) 下載進度回調
- onAppInfos(viewData) app詳情頁面數據准備完畢回調
ControllerDownLoadInterface
- downLoadIamgeComplate(url) 圖片下載完成回調
- doanloadTemplateComplate(id) 模板下載完成回調
- downloadAppsByTempComplate(id) 模板數據下載完成回調
ControllerDownLoadAppInfo
- downLoadAppStart(id) 開始下載app回調
- downLoadAppProgress(id, progress) app下載中進度回調
它需要依賴的接口ControllerDependInterface(虛類,或接口)。
1 針對網絡請求
- downloadImage(url) 添加下載圖片
- downloadTemplateById(id) 下載模板
- downloadAppsByTemp(id) 下載模板對應的app信息
2 針對網絡請求的數據處理
- setData(temp, apps) 進行模板和app數據組合
- setAppInfo(appinfos) 進行模板和app詳情組合
- getViewDataByTempId() 獲取組合后的viewData
- getIamgeByUrl(url) 獲取圖片
- getAppsInfoData(id) 獲取組合后的app詳情數據
3 針對app下載
- startDownLoad() 開始下載
- setDownLoadApps(appinfo); 添加下載項
我們好好分析一下調度模塊,它有二個功能,第一通過調度各個業務單元,從而實現整個業務。接受到界面指令之后,對指令進行拆分,綜合結果並且上報。這樣做的好處是業務統一處理。第二,它分割UI和各個業務單元緊密關聯,通過添加一個層來隔離UI和各個業務,使得UI層和各個業務單元各自為政,互不干系。這樣做的好處是業務單元不直接影響UI,結構扁平,增加穩定性。
但是這也有不好處,如果業務龐大的話,這樣的調度模塊就顯得臃腫。當然了,另一個方法就是數據處理模塊依賴網絡模塊,而調度模塊不再依賴網絡模塊。這樣由扁平成了垂直設計,無論怎么樣,只要模塊划分差不多,就容易在進行下去了。
模塊划分就說明在這里。明天說合理組合部分。