這篇文章主要是對工作兩年來用過的架構(gòu)發(fā)表一下自己感觸,如果說的不對請輕噴.
關(guān)于架構(gòu)
??????根據(jù)百科中的軟件架構(gòu),架構(gòu)描述的對象是直接構(gòu)成系統(tǒng)的抽象組件,各個組件之間的連接則明確和相對細致地描述組件之間的通訊口四。在實現(xiàn)階段酒甸,這些抽象組件被細化為實際的組件,比如具體某個類或者對象....Android架構(gòu)目前有許多不同的模式脯燃,如MVP, FLUX, MVI, MVVM等.我們當然知道,還用在這bb!!!
????挖干的說,決定和實現(xiàn)一個特定的代碼體系結(jié)構(gòu)或設(shè)計模式都是為了解決我們開發(fā)人員時常面對的問題挨稿。
一些問題
??????說到問題我可能有很多要吐槽的了,剛爬進Android這個坑,因為Android本身被寫為MVC,所以用的就是MVC模式,那時候只是簡單的寫一些簡單的功能,一個activity處理所有工作,顯示View,網(wǎng)絡(luò)請求,但是畢竟功能簡單,一個activity也不會超過百行,所以不會考慮什么耦合,性能問題.對于簡單的應(yīng)用來說,這可能是足夠的严拒,但是隨著復(fù)雜性的增加,問題的數(shù)量和水平也會上升竖独。
??????正式投入Android開發(fā)崗位,因為項目前期由一個人完成,所以寫的很隨意(你懂得),一些業(yè)務(wù)邏輯稍微復(fù)雜的activity或者Fragment超過3000行代碼是很正常的,看的時候都不知道從哪開始,每次想要修改點功能都要耗費大量時間看代碼邏輯...如果繼續(xù)這樣代碼堆砌最后肯定得崩,所以決定采用大家都在口口相傳的MVP模式來進行解耦合.當時對于MVP不是很熟,然后一開始的寫法是把回調(diào)接口寫到一個單獨的接口中,一個activity對應(yīng)一個iview,像這種
public class xxPresenter implements xxContract.Presenter {
activity或者Fragment實現(xiàn)contract中的view的方法,
public class xxFragment implements xxContract.View {
這樣確實做到了view和邏輯的解耦.
??????愉快的開發(fā)了一段時間后,發(fā)現(xiàn)每當我有兩個功能相近的頁面,而且還要同樣的一個請求方法,于是想復(fù)用一個contract中的presenter中方法,然后就會造成在某個頁面的中會有多余的空方法,而且還不能刪除,
??????這就是使用的mvp的歷程,代碼的緊密耦合裤唠,即使是代碼中的一小部分的更改,也會導(dǎo)致代碼的其他部分的更改或者引起錯誤莹痢。減少了可重用性种蘸,最終導(dǎo)致代碼復(fù)制粘貼,冗余嚴重,就不要再說什么單元測試之類的.
為什么MVVM…?竞膳?
??????我們最終的目標是以這樣一種分布式的方式構(gòu)建項目航瞭,將Android相關(guān)的東西放在一個地方,并分離出不需要Android運行的所有其他實體坦辟,然后進一步分割非Android相關(guān)的片段刊侯,從而實現(xiàn)代碼模塊化、可擴展性长窄、易維護性滔吠、測試友好性等。
??????我們會在公眾號博客和技術(shù)網(wǎng)站上看到無數(shù)關(guān)于架構(gòu)模式的文章和架構(gòu)設(shè)計教程的文章,毫無疑問現(xiàn)在最流行和廣泛采用的是MVP~Model—View—Presenter.說明MVP是一個成熟的模式挠日,在一定程度上解決了很多方面的問題疮绷,但是也會有上面我提出的問題。當然了沒有什么是完美的嚣潜,總有一個改進的余地冬骚。但與此同時谷歌引入了Android架構(gòu)組件,其中包括ViewModel而不是Presenter懂算,因此證明了谷歌支持MVVM只冻。
??????可能這些并不能說明MVVM比MVP好,那就讓我們看看上述MVP中所面臨的幾個問題,MVVM是如何來克服的计技。
1.代碼耦合
??????對于每個Activity/Fragment喜德,我們需要一個Presenter,這是一個硬束縛的規(guī)則。Presenter持有對Activity的引用和Activity持有Presenter的參考,兩者1:1的關(guān)系垮媒,就是最大的問題所在舍悯。隨著視圖的復(fù)雜性的增加,對這種關(guān)系的維護和處理也隨之增加睡雇。而我們的最終目標以分布式的方式構(gòu)建項目萌衬,對項目做分割,為了實現(xiàn)這個目標并避免這種緊密關(guān)系的ViewModel被引入。
??????ViewModel是負責為activity或Fragment準備和管理數(shù)據(jù)的類,它還處理activity或Fragment與應(yīng)用程序的其余部分的通信(例如調(diào)用業(yè)務(wù)邏輯類)它抱。只有View(比如activity)持有對ViewModel的引用秕豫,而ViewModel卻不持有任何View,這就解決了我們的緊密耦合問題观蓄。同時一個View可以引用多個ViewModel混移。即使對于復(fù)雜的視圖祠墅,我們實際上可以在相同的層次結(jié)構(gòu)中擁有不同的ViewModel。
2.接口冗余
??????使用這種方式不用寫很多的接口,因為ViewModel中會提供數(shù)據(jù),如果需要使用數(shù)據(jù)時可以直接從viewmodel中獲取到,不像MVP那樣通過接口來回調(diào)數(shù)據(jù),這樣就不會寫很多的接口,也不會又接口聲明沒有使用的情況.
3.可測試性
??????由于Presenter很難綁定到View沫屡,所以編寫單元測試變得有點困難饵隙,因為View有很多的依賴關(guān)系撮珠。
??????ViewModel在單元測試會容易一些沮脖,因為它們只是暴露狀態(tài),因此可以獨立測試芯急,而不需要測試數(shù)據(jù)將如何被消耗勺届,總之,是不依賴于View的娶耍。
??????這是幾個選擇MVVM的原因,可能你也有更多原因免姿,期待你的分享!榕酒!
一點感想
??????架構(gòu)模式是不斷發(fā)展的胚膊,MVVM有能力或者說有潛力變成更加強大,有用想鹰,令人驚訝的模式紊婉。而MVP已經(jīng)發(fā)展到一個相當高的水平,但金無足赤,沒有任何東西是完美的辑舷。當然學習MVVM有一點輕微的學習曲線喻犁,當時也是試驗了好久,但最終它幫助我們克服了一些缺點。有人可能喜歡MVVM何缓,也可能不喜歡MVVM肢础,這完全取決于他們的判斷。但我是喜歡的那個,同事也是用了都說好的那種,哈哈,只要我們能達成最終目標碌廓,其他事情都無關(guān)緊要传轰。
PS:再次重申,這是我個人的一點經(jīng)驗、想法以及我們?yōu)槭裁从肕VVM重構(gòu)項目谷婆。請不要懷疑我的意圖,我并不是想比較和找出差異慨蛙。我所想的是分享我的經(jīng)驗和MVP的一些缺點,以及如何用MVVM克服波材。如果惹鬧了您,請輕噴,謝謝