我們經常在感嘆,技術更新換代太快,但是不管怎么變,永遠不變的一個核心思想就是“調用更加方便、更加安全、架構清晰,代碼簡潔、反對臃腫、代碼之間的耦合度更低”,這是一個好的軟件永遠追求的目標。
本文出自門心叼龍的博客,屬于原創類容,轉載請注明出處。https://blog.csdn.net/geduo_83/article/details/88937994
忙了將近兩個月,也算告一段落,一直打算寫一篇關于項目架構方面的文章,也是對這段時間工作的一個歸納總結,正好清明節放了三天假,難得有時間...
一周科技雜談:
上個周,王興團長在接受境外媒體參訪的時候,舊事重提了當年支付寶獨立的陳芝麻爛谷子的事兒,指責馬云有誠信問題,這件事兒其實和美團一點關系都沒有,這事兒還不夠,又發了一個朋友圈對阿里的人事進行指手畫腳,給阿里指定“太子”。去年還是東哥的輿論場,如今卻變成了王興輿論場,眾所周知,東哥由于明尼蘇達事件已經是身敗名裂,現在是徹底退居二線了,東哥現在確實低調了很多,微博個性簽名都改成了,“低調,低調,在低調”。
我們還記得在2017年烏鎮世界互聯網大會上東哥和王興組了聲勢浩大晚宴“東興”局,照片一出,馬云騰C位正襟危坐,左右分別是劉強東和王興,其他各互聯網大佬都列作于此,唯獨不見馬云,明眼人都能看出來,這就是要孤立馬云,隨后劉強東參加了“共享紅利--互聯網精準扶貧”的論壇,劉強東講到:“有人說一個月賺幾十億已經成為讓人痛苦的事情,在我國還有幾千萬的生活在極端貧困的狀態,這是中國已經富起來的這些人的恥辱”,很明顯這話是在懟馬云。
事后,馬云在接受媒體采訪時說“我馬云豈能是一場飯局就能擊垮的,我可以把世界級的大佬邀請來,也搞一個有必要嗎?沒有”,這就是馬老師的格局,隨后劉強東異常高調,但是還不到一年的時間,就出了劉強性情事件的丑聞,估計馬云聽到這事情會大笑三天三夜。現在東哥消停了,王團長又來了,不管是蹭熱度還是有其他什么目的,但是在公開場合作為企業創始人公開懟別人,這就是你的不對了,俗話說:“凡事留一線,日后好見面”,劉強東的事兒雖然沒有觸犯法律,但是卻徹底失聲了,自己也是身敗名裂,企業形象嚴重受損,有人說被人“做局了”,我想無論是有沒有被“做局”,但是事情你終歸還是做了,就是被人做局,也是別人抓住了你的人性的弱點。用當年上大學時宿舍里面經常說的一句陜西口頭禪:“娃是好娃,女人把娃害了”。
企業之間競爭不可避免,搞團團伙伙,拉幫結派,公開懟,這就有些太小肚雞腸,小人形象暴露無遺,劉強東徹底消停了,王興又來了,我想這小子會不會是下個東哥?平日除了研究技術,最大的愛好就是寫毛筆字練書法,最愛寫的八個字就是,“上善若水”、“厚德載物”,水利萬物而不爭,君子以厚德載物,如果德不配位,早晚遭殃。
項目架構的重要性:
好了,我們言歸正傳,我們在前面幾篇文章談到了一些項目架構的問題,年前寫了一篇“Android組件化最佳實踐”,年后寫了一篇“淺談單一結構體項目的組件化改造”,我們提到了單一結構項目里,結構混亂,層次不清,有些模塊同一功能解決方案不統一、有了新需求只是在原有項目上不斷的砌代碼罷了。長此以往,整個項目就是鐵板一塊,為后期的項目維護和擴展造成了極大的困難。
我們在軟件開發的時候,在做一個項目之前,架構師做工作就是搭項目框架,這是一個前提工作,給整個項目制定開發標準,開發規范,如果沒有規范,項目可以搞起來嗎?當然可以,就是個開發人員各行其是,最后的結果就是,項目做完了,整個項目結構混亂,層次不清。反之,一旦形成自己的一套框架體系,就可以長期使用,甚至成為整個公司的一套開發標準,大大提高后期的項目開發效率,來了新項目就直接可以在新項目中使用,而把主要的精力放在業務功能的實現上。
架構的變:
前陣子在一個技術群里面,有人說他們現在還用的是傳統的架構MVC的架構,覺得挺好,甚至還在用ListView,我只能說,你感覺良好就行,有這種情況嗎?肯定有,以前的一些老技術,老方案,能實現嗎?當然可以,可以實現具體的開發要求,就好比你去理發店理發,你進店之后,前臺就會問你,你要找那個老師給你理?我們這里有20塊的,也有50塊,最高是200塊的,問你要選一種?20塊也能做,200塊也能做,價格卻整整差了10倍,為什么?這就是不同老師他們水平不一樣,做法不一樣罷了,你20元有20元的做法,你200元當然有200元的做法,我們做軟件開發也一樣,同一個項目,你給兩千元有兩千架構的做法,你給二十萬也有二十萬元的架構的做法,最終功能都能實現,只是軟件質量不同罷了。
架構的不變:
在后移動時代我的一些思考的這篇文章里,我們談到這是一個知識爆炸的時代,尤其是做技術這一行業的,不像一些傳統的行業,例如醫生、律師這些知識結構相對穩定的行業,做技術的我們時常會深深的體會到技術更新換代太快了,我們一項新技術還沒有研究透徹,就又有新的技術來替代它了,但是不管技術怎么變,但是永遠不變的一個核心思想就是“調用更加方便、更加安全、代碼之間的耦合度更低”,這是一個好的軟件永遠追求的目標。
代碼質量問題:
同樣的一個功能初級工程師能實現嗎?可以,高級工程師可以做嗎?當然也可以,有何不同?可能高級工程師1個小時就能實現的功能,作為一個初級工程師可能需要1天時間才能完成,一個高級工程師可能需要50行代碼實現的問題,初級工程師可能花了兩三百行才能搞定,高級工程師實現的功能bug率很低,而初級工程師可能一測試到處都是bug,這就是區別,這就是軟件的質量不同。
當然,在實際工作當中有很多時候,項目需要趕進度,領導看的是結果,就看你功能實現了沒有?你沒有辦法,只能選擇做20元了,因為你想要做好,你就需要花更多的時間了,而現在沒有人給你這個時間去做這個工作。
代碼簡潔之道:
在唐代有一位大詩人叫白居易,他每作一首詩,都要給不識字的老太太念念,老太太能聽懂的,就要,聽不大懂的,就改,這也是為什么他的詩一直在民間廣為流傳,而且還流傳到了日本,而我們寫代碼也是一樣的道理,越簡單也好,我曾經看過別人寫的一個關于app應用市場下載的功能,一個簡單的功能搞了十幾個類,各個類之間層次不清,引用關系混亂,實在讓人看不下去,一個好的工程師,不在于你寫了多么復雜的功能,而在于你寫了一個多么好的功能,代碼簡潔,結構清晰,人人都能看懂,這才是好代碼,反對臃腫,真正的做到了簡約而不簡單,這才是編碼高手。
Android應用架構發展史:
一代MVC架構:
- Model: 用于封裝與應用程序的業務邏輯相關的數據以及對數據的處理方法
- View: 渲染頁面
- Controller: 控制器,他是M和V之間的連接器,處理相關的業務邏輯
標準的MVC架構它的工作流程:
- View接受用戶的交互請求
- View將請求轉交給Controller
- Controller操作Model進行數據更新
- 數據更新之后,Model通知View數據變化
- View顯示更新之后的數據
MVC工作流程圖:
在最早從事android開發這批人員,最早使用的是都是MVC架構,這是一種非標準的MVC架構,因為Activity及承擔Controller的角色,又承擔了View的角色。Activity 和 Fragment 越來越多的同時承擔了 Controller 和 View 的職責,導致他們變得及其臃腫且難以維護,由于 Controller 和 View 的揉合,回調嵌套太多,代碼邏輯不清晰,難以理解且不利于后期維護,各層次模塊之間職責不清晰等等。
二代MVP架構:
在2016年,Google 推出的基于 MVP 架構的 Demo 后,我們發現 MVP 架構能解決現在所面臨過的很多問題
MVP工作流程圖:
- View接受用戶的交互請求
- View將請求轉交給Presenter
- Presenter操作Model進行數據庫更新
- 數據更新之后,Model通知Presenter數據發生變化
- Presenter更新View的數據
MVP架構圖如下:
- View Layer: 負責繪制UI元素、與用戶進行交互,對應于xml、Activity、Fragment、Adapter,包含一些自定義的 UI 組件
- Model Layer: 負責檢索、存儲、操作數據,包括來自網絡、數據庫、磁盤文件和SharedPreferences的數據
- Presenter Layer: 作為 View Layer 和 Module Layer 的之間的紐帶,它從 Model 層中獲取數據,然后調用 View 的接口去把數據顯示在View上
- Contract: 參照 Google 的 Demo 加入契約類 Contract 來統一管理 View 和 Presenter 的接口,使得某一功能模塊的接口能更加直觀的呈現出來,這樣做是有利于后期維護的。
盡管這樣,MVP模式也有不足之處,不然也不會推出MVVM了,缺點如下:
- Presente層與View層是通過接口進行交互的,View層可能會有大量的接口,因為有可能好幾個Activity都是去實現同一個View接口,那么所有用到的Activity都要去實現所有的方法(不管你是否用到),而且如果后面有些方法要刪改,Presenter和Activity都要改動,比較麻煩;
- MVP把Activity相當的一部分責任放到了Presenter來處理,復雜的業務同時也可能會導致P層太大,一旦業務邏輯越來越多,View定義的方法越來越多,會造成Activity和Fragment實現的方法越來越多,依然臃腫。
三代MVVM架構:
相對于 MVC 的歷史來說,MVVM 是一個相當新的架構,MVVM模式不是四層,任然是3層,分別是Model、View、ViewModel,MVVM 在使用當中,通常還會利用雙向綁定技術,使得 Model 變化時,ViewModel 會自動更新,而 ViewModel 變化時,View 也會自動變化。所以,MVVM 模式有些時候又被稱作:model-view-binder 模式。
MVVM 在實際使用中,確實能夠使得 Model 層和 View 層解耦,但是如果你需要實現 MVVM 中的雙向綁定的話,那么通常就需要引入更多復雜的框架來實現了。
- View:視圖層,采用XML文件進行界面的描述
- Model:模型層,通過網絡和本地數據庫獲取視圖層所需數據
- ViewModel:視圖-模型層,負責View和Model之間的通信,以此分離視圖和數據
工作流程:
- View中使用DataBinding的Command來綁定事件和響應事件,觸發網絡請求
- ViewModel進行分析處理,調用Model的方法去請求數據
- Model將收到的請求參數等信息封裝,調用網絡請求庫
- 服務器將數據返回Retrofit等網絡庫,再返回到Model層中
- ViewModel在回調中收到返回的實體類對象
- 因為xml與實體類對象實現了雙向綁定,實體類更新,使得UI更新
MVVM也存在著自己的一些缺點:
- 數據綁定使得 Bug 很難被調試。你看到界面異常了,有可能是你 View 的代碼有 Bug,也可能是 Model 的代碼有問題。數據綁定使得一個位置的 Bug 被快速傳遞到別的位置,要定位原始出問題的地方就變得不那么容易了
- 對于過大的項目,數據綁定需要花費更多的內存
某種意義上來說,我認為就是數據綁定使得 MVVM 變得復雜和難用了
四代架構MVP+組件化
前面講的這三種android開發中常用的項目架構,不管是哪一種架構,它始終是一個單一結構體項目,各個模塊之間還是以傳統的包名來區分的,其各個模塊還是強耦合在一的,自然而然組件化的方案就出現了,組件化有開發模式和發布模式之分,在開發模式下每個業務模塊都是都是一個獨立的apk,在發布模式打包的時候,每個業務模塊都變成了一個個獨立的組件library,這就完成了各個模塊之間的徹底解耦。
今年開年以來公司就上了一個新項目Vcars,就采用了MVP + 組件化的解決方案,現在通過文字的形式把它記錄下來,也是對這段時間工作的一個歸納總結。
Vcars組件化架構圖:
- 集成模式:所有的業務組件被“app殼工程”依賴,組成一個完整的APP;
- 組件模式:可以獨立開發業務組件,每一個業務組件就是一個APP;
- app殼工程:負責管理各個業務組件,和打包apk,沒有具體的業務功能;
- 業務組件:根據公司具體業務而獨立形成一個的工程;
- 功能組件:提供開發APP的某些基礎功能,例如打印日志、下拉刷新控件等;
- Main組件:屬于業務組件,指定APP啟動頁面、主界面;
- Common組件:屬于功能組件,支撐業務組件的基礎,提供多數業務組件需要的功能
Vcars項目類圖
-
Activity關系圖:
在這里插入圖片描述 -
Fragment類關系圖:
在這里插入圖片描述 -
BaseRefreshActivity類圖:
在這里插入圖片描述 -
BasePresenter類關系圖:
在這里插入圖片描述 -
BaseModel類關系圖:
在這里插入圖片描述
總結:
整體來看MVVM 比MVC/MVP精簡了很多,不僅僅簡化了業務與界面的依賴,在MVVM中,View不知道Model的存在,ViewModel和Model也察覺不到View,這種低耦合模式可以使開發過程更加容易,提高應用的可重用性。
不管是MVC,MVP還是MVVM,他們都屬于項目的編碼架構,而組件化是整個工程的工程架構,它的主要意義在于,對原來以包來區分的各個模塊進行完全的解耦,但是不管技術怎么怎么更新換代,但是永遠不變的一個核心思想就是“調用更加方便、更加安全、代碼之間的耦合度更低”,這是一個好的軟件永遠追求的目標。