在實際項目開發中,咱們曾無數次地吐槽剛接手的app太亂無法維護,內心曾有無數只草泥馬走過。做爲高素質時刻爲他人着想的高端人才,咱們固然要爲接手者鋪好路,畢竟你們都不容易啊,程序員何苦難爲程序員?因此咱們必定要注重app架構的優化,並且是在app剛開發時就應該考慮到架構的設計,那麼應該如何去設計一個app的架構呢?做者給你們簡單分享一下本身的心得,以及一些經驗tips,但願能對你們有所幫助。程序員
1、知足solid原則
json
在咱們面向對象的開發者看來,外物皆對象。其實一個app也不例外,這裏面有不少的共通性,咱們也能夠把它當作一個大的對象。那麼咱們在設計一個app架構的時候就應該考慮到面向對象的五大solid原則,它們分別是:單一職責原則、開放封閉原則、裏式替換原則、接口分離原則、依賴倒置原則。緩存
單一職責原則:一個類只作一種類型責任,當這個類須要承當其餘類型的責任的時候,就須要分解這個類,這是解耦的重要步驟網絡
開放封閉原則:對擴展開放,對修改關閉,好比使用代理模式架構
裏式替換原則:當一個子類的實例應該可以替換任何其超類的實例時,它們之間才具備is-A關係,也就是說不能模糊化類的概念,類的設計必定要嚴謹app
接口分離原則:不要強迫使用不須要的接口,也就是說使用多個功能專注的接口比使用一個總接口要更好框架
依賴倒置原則:在須要依賴關係的地方儘可能依賴接口和抽象類,而不是具體類模塊化
2、視圖、數據、邏輯分離組件化
將視圖、數據、邏輯分離分離有不少好處,好比便於維護、提高複用性、增長容錯性等,這裏經常使用的分離架構有MVC、MVP、MVVM等。若是不進行分離,最後的結果會是全部非靜態佈局代碼都在Activity中,出現一個文件打天下的狀況,最後維護起來兼職就是噩夢,這是咱們要避免的,好的app架構不該該出現這種狀況。佈局
MVC:獲取數據的操做放到Model層,xml佈局文件至關因而V層,Activity/Fragment至關因而C層,全部業務代碼和界面都放到Controller中。雖然把獲取數據抽象出了Model層,但C層依然太臃腫,這種模式通常只應用於很簡單業務邏輯很少的界面,優勢是寫起來簡單。
MVP:獲取數據的操做放到Model層,Activity/Fragment此時至關因而V層,這是和MVC第一個不同的地方,第二個不同的地方是新增了Presenter來處理具體的業務邏輯,而V層只負責界面的顯示相關邏輯,瞬間簡潔了很多。當前MVP也有瑕疵,就是若是業務邏輯複雜的話,Presenter裏要處理的內容過多,會致使Presenter很臃腫,不堪重負。
MVVM:獲取數據的操做放到Model層,Activity/Fragment此時至關因而V層,而後新增了一個ViewModel層,經過DataBinding來將ViewModel跟佈局文件進行綁定,從而將填充數據等邏輯直接廢除,缺點是上手較慢一些,由於DataBinding仍是有必定學習成本的。
總結:在實際業務中具體使用哪種應該根據實際狀況來定,若是是很簡單的業務能夠用MVC,通常是用MVP或者MVVM更好一些。
3、模塊化架構
咱們應該將那些固定的模塊進行抽離,將重要的模塊進行解耦,因此必須對app中的代碼進行模塊化架構。常見的分層方式是分爲7層,分別是硬件、操做系統、JNI、Base、網絡、common、業務模塊。當前這並不表明最優,可是也是比較常見的劃分模塊的方式。前面3個是底層模塊這裏就不闡述,下面說一下其餘4個模塊的內容和依賴關係。
Base:存放接口抽象類util類等基礎的類,只要後期穩定了基本都不須要修改,可是牽一髮動全身,通常由架構師或高級程序員來維護。Base就是最基本的模塊,不依賴任何模塊。
網絡:這裏是存放網絡請求用到的一些類,好比網絡框架代碼、網絡錯誤處理、添加固定header等,網絡層依賴於base層,由於須要base層的一些基類
common:這裏是存放各個業務模塊都須要用到的類,常見的好比自定義view,能夠在各個業務中複用的時候,能夠存放到common層,common模塊也依賴於base模塊。
業務模塊:實際的業務代碼,依賴於common層和網絡層,這裏可使用組件化進行架構。因爲組件化通訊比較複雜,具體後面會從新開一篇文章來詳細說明。
4、重要數據內置和緩存
爲了提高app在用戶沒網時的體驗,在主流app中都會對數據進行緩存,在沒網時顯示緩存內容。而後在下次打開app或者先後臺切換時更改緩存文件,達到更新的目的。也能夠在界面顯示時對界面進行更新,不過這樣作可能會形成閃爍,很是影響用戶體驗,這裏不推薦這種作法。
除此以外,爲了防止新用戶首次打開app就出現網絡不佳的狀況,咱們須要對重要數據進行內置,若是是列表咱們能夠只內置一頁數據。內置方式就是將數據以json的形式保存在asset下的文件裏,而後運行時從asset下讀取而且解析到內存中使用。內置內容通常只在第一次打開app時可能會用到,後面都是用緩存內容進行顯示。
5、其餘經驗之談
1.咱們能夠在網絡層寫好,debug模式下自動打印出請求參數和返回值,方便開發時進行調試
2.網絡請求時不一樣的錯誤須要進行區分處理,而且向服務端打點,方便查找問題
3.base層應該支持在實際界面關閉時取消網絡請求,防止作無用操做,節省內存開銷
4.若是是MVVM業務結構的話,須要注意的是若是ViewModel持有view的對象時應該使用弱引用的方式,而後應該在view關閉的生命週期中對該持有進行清除操做,防止內存泄漏
5.在須要切換同一佈局的內容顯示時,爲了不重複的顯示隱藏判斷操做,可使用TipsView
6.在一些簡單app中沒有splash倒計時功能,此時要解決打開app白屏問題的話,咱們仍然能夠新建一個SplashActivity,此時能夠在splash的onpause中關閉當前頁面
最後:以上幾點是很重要的經驗,但也不表明考慮了這些點就是最優秀的架構了。實際項目遠比理論複雜,因此咱們須要作的是借鑑別人的經驗,來解決本身的實際問題。做者之後有其餘的經驗也會更新上去,但願能給你們帶來一些幫助。