如何設計app架構?

冬榮發表於1970-01-01

在實際專案開發中,我們曾無數次地吐槽剛接手的app太亂沒法維護,心裡曾有無數只草泥馬走過。作為高素質時刻為他人著想的高階人才,我們當然要為接手者鋪好路,畢竟大家都不容易啊,程式設計師何苦難為程式設計師?所以我們一定要注重app架構的優化,而且是在app剛開發時就應該考慮到架構的設計,那麼應該如何去設計一個app的架構呢?作者給大家簡單分享一下自己的心得,以及一些經驗tips,希望能對大家有所幫助。


一、滿足solid原則

在我們物件導向的開發者看來,外物皆物件。其實一個app也不例外,這裡面有很多的共通性,我們也可以把它當做一個大的物件。那麼我們在設計一個app架構的時候就應該考慮到物件導向的五大solid原則,它們分別是:單一職責原則、開放封閉原則、裡式替換原則、介面分離原則、依賴倒置原則。

單一職責原則:一個類只做一種型別責任,當這個類需要承當其他型別的責任的時候,就需要分解這個類,這是解耦的重要步驟

開放封閉原則:對擴充套件開放,對修改關閉,比如使用代理模式

裡式替換原則:當一個子類的例項應該能夠替換任何其超類的例項時,它們之間才具有is-A關係,也就是說不能模糊化類的概念,類的設計一定要嚴謹

介面分離原則:不要強迫使用不需要的介面,也就是說使用多個功能專一的介面比使用一個總介面要更好

依賴倒置原則:在需要依賴關係的地方儘量依賴介面和抽象類,而不是具體類


二、檢視、資料、邏輯分離

將檢視、資料、邏輯分離分離有很多好處,比如便於維護、提升複用性、增加容錯性等,這裡常用的分離架構有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更好一些。


三、模組化架構

我們應該將那些固定的模組進行抽離,將重要的模組進行解耦,所以必須對app中的程式碼進行模組化架構。常見的分層方式是分為7層,分別是硬體、作業系統、JNI、Base、網路、common、業務模組。當前這並不代表最優,但是也是比較常見的劃分模組的方式。前面3個是底層模組這裡就不闡述,下面說一下其他4個模組的內容和依賴關係。

Base:存放介面抽象類util類等基礎的類,只要後期穩定了基本都不需要修改,但是牽一髮動全身,一般由架構師或高階程式設計師來維護。Base就是最基本的模組,不依賴任何模組。

網路:這裡是存放網路請求用到的一些類,比如網路框架程式碼、網路錯誤處理、新增固定header等,網路層依賴於base層,因為需要base層的一些基類

common:這裡是存放各個業務模組都需要用到的類,常見的比如自定義view,可以在各個業務中複用的時候,可以存放到common層,common模組也依賴於base模組。

業務模組:實際的業務程式碼,依賴於common層和網路層,這裡可以使用元件化進行架構。由於元件化通訊比較複雜,具體後面會重新開一篇文章來詳細說明。

如何設計app架構?


四、重要資料內建和快取

為了提升app在使用者沒網時的體驗,在主流app中都會對資料進行快取,在沒網時顯示快取內容。然後在下次開啟app或者前後臺切換時更改快取檔案,達到更新的目的。也可以在介面顯示時對介面進行更新,不過這樣做可能會造成閃爍,非常影響使用者體驗,這裡不推薦這種做法。

除此之外,為了防止新使用者首次開啟app就出現網路不佳的情況,我們需要對重要資料進行內建,如果是列表我們可以只內建一頁資料。內建方式就是將資料以json的形式儲存在asset下的檔案裡,然後執行時從asset下讀取並且解析到記憶體中使用。內建內容一般只在第一次開啟app時可能會用到,後面都是用快取內容進行顯示。


五、其他經驗之談

1.我們可以在網路層寫好,debug模式下自動列印出請求引數和返回值,方便開發時進行除錯

2.網路請求時不同的錯誤需要進行區分處理,並且向服務端打點,方便查詢問題

3.base層應該支援在實際介面關閉時取消網路請求,防止做無用操作,節省記憶體開銷

4.如果是MVVM業務結構的話,需要注意的是如果ViewModel持有view的物件時應該使用弱引用的方式,然後應該在view關閉的生命週期中對該持有進行清除操作,防止記憶體洩漏

5.在需要切換同一佈局的內容顯示時,為了避免重複的顯示隱藏判斷操作,可以使用TipsView

6.在一些簡單app中沒有splash倒數計時功能,此時要解決開啟app白屏問題的話,我們仍然可以新建一個SplashActivity,此時可以在splash的onpause中關閉當前頁面


最後:以上幾點是很重要的經驗,但也不代表考慮了這些點就是最優秀的架構了。實際專案遠比理論複雜,所以我們需要做的是借鑑別人的經驗,來解決自己的實際問題。作者以後有其他的經驗也會更新上去,希望能給大家帶來一些幫助。


相關文章