本文由
玉剛說寫做平臺
提供寫做贊助前端原做者:
Mr.S
react版權聲明:本文版權歸微信公衆號
玉剛說
全部,未經許可,不得以任何形式轉載android
架構就像是一場進化史,根據不一樣時期的需求,演變出不一樣的架構,車輪滾滾,到今天,移動端框架百花齊放,讓人應接不暇。可是其中的本質是磨滅不了的,換言之根本沒有磨滅而是隱藏到了人們所看不到的地方,可是依舊發揮着不可或缺的做用。ios
爲何須要架構?數據庫
當咱們新進一個公司,接受別人的項目的時候,基本都會說句MMP,SHI同樣的代碼啊,啥玩意啊,搞得什麼啊。編程
我擦,我就改了一個參數,怎麼全亂套了,一個功能怎麼天上地下都須要改啊。服務器
沒有經受過痛苦的人,是不會想了解架構的,只有痛苦過的人,纔會急切的瞭解架構,好好作人,不做孽。微信
進化1.0 MVC架構
人們剛接觸編程,相信第一個遇到的框架就是MVC,無論你經意仍是不經意寫出來的Android程序他就是MVC框架,只不過是MVC框架的某一個變種(最混亂的那種)。Android系統自己就根據MVC建造的。併發
咱們編寫程序剛開始應該是這種結構
View層和Controller交織在一塊兒。在Activity裏面處理各類事件和邏輯,界面的顯示和更新都在這裏,除了按功能分出去的模塊外,能在Activity裏面寫的都會堆在這裏面,代碼經常達到上千行,別說別人,本身再回到頭看的時候也是頭皮發發麻。
因此咱們開始試着學Android系統的MVC來梳理代碼。固然每一個人從衆理解的也不大同樣。 無論是單向依賴仍是雙向依賴都是爲了把處理的職責交給Controller,這一點是不變的,因此無論你用的是哪種形式都是不打緊的,沒有對與錯。根據本身的需求選擇最適合的一種依賴關係。
因爲MVC很好的分離了視圖層和業務層,因此它具備如下優勢
MVC使用的誤區
其實我在剛開始編程的時候,
正解:是MVC的Model應該有兩個功能:
正解:Model也會處理業務邏輯
這兩個誤區其實也和MVC的構成有關係,很容易讓人誤解,可是本質上仍是不理解MVC,特別是對Model的做用不明白。
其實Model在MVC框架裏面的做用不只僅是Entry,Model在MVC中起着很重要的做用,它更應該是業務邏輯的真正實現層,而Controller層更應該做爲一個橋接的做用,把View的求情轉發給Model,再把Model處理結束的消息告訴View。這樣作也就是界面和代碼(邏輯)分離。
進化2.0 MVP
可是踏入誤區的人太多了,你們都在Activity裏面處理邏輯由於太方便了(寫的很爽)。 可是這樣以後,咱們Activity的職責太多了,耦合也嚴重,因此咱們就想着怎麼能給Activity減負,同時把耦合也降下來,因此就想找個哥們來替Activity分擔的責任,你們最後都只有一個責任,各層關係也相對好理解,你們照着這個方式寫,那多好,不用加班,每天都很快樂。
既然Activty這麼願意和View搞到一塊兒(解耦過高了),那麼就讓他們倆在一塊兒(在一塊兒,在一塊兒,在一塊兒),共同負責View,咱們在招聘一個職業經理人(Presenter)來處理事務,有啥事都找Presenter,你看着多方便啊,MVP是一個真正意義上的隔離View的細節和複雜性的模式
至於虛線的部分,這個和樓上的MVC的虛線同樣,每一個人的理解不一樣,狀況不一樣,選擇合適的就好,不用糾結誰對對錯,本質不變就能夠的。
這樣就簡單多了,Activity和View兩人各類膩歪秀恩愛,各層的關係也一目瞭然,你們各幹各的事情,想要什麼和Presenter說一聲,有啥事情Presenter也會彙報,簡直爽的不要不要的。Presenter也會處理和View層的交互,Presenter在手天下我有。
一、模型與視圖徹底分離(就像牛郎和和織女隔了一個銀河,每次都須要靠燕子來傳信,好可憐~~)
二、能夠更高效地使用模型,由於全部的交互都發生在一個地方——Presenter內部
三、(Presener的複用)一個Presener能夠用於多個視圖(View),而不須要改變Presenter的邏輯。視圖(View)的變化比模型(Model)的變化更頻繁的多 ,因此這樣超級方便。
四、(View的複用)View能夠進行組件化。在MVP當中,View不依賴Model。這樣就可讓View從特定的業務場景中脫離出來,能夠說View能夠作到對業務邏輯徹底無知。它只須要提供一系列接口提供給上層操做。這樣就能夠作高度可複用的View組件。
五、更容易單元測試
一、因爲對視圖的渲染放在了Presenter中,因此視圖View和Presenter的交互會過於頻繁。特別是須要修改視圖的時候,Presenter也須要跟着修改,很麻煩。
二、Presenter中除了業務邏輯之外,還有大量的View->Model,Model->View的手動同步邏輯,形成Presenter比較笨重,維護起來會比較困難。
三、其實總的來講就是結構很清晰,業務邏輯也很明白,耦合低,可是就是本身寫的麻煩,Presenter很差維護,工做量太大,太笨重,有點像MVC中的Activity了,職責太多了。也能夠把這三個缺點總結成一句話,麻煩,尾大不掉。
進化3.0 MVVM
可是吧,大家爽了Presenter可就累壞了,大事小事都要通過Presenter,就連放個屁也要Presenter來扒褲子,日子過得久了,Presenter總會有意見啊,不帶這麼使喚人的。
咱們就想啊,之前過多的依賴Activity形成結構混亂,耦合過高,後來有了Presenter,雖然耦合大大下降,可是仍是過於依賴Presenter,爲啥總會過於依賴某一個東西呢,就不能你們都乾點活,耦合性也不高的嗎?就不能你們有事相互通知嗎?非要那麼懶依賴別人嗎?總要有點正能量吧。那麼咱們就把Presenter辭退,引入了一個新的小夥伴VM(ViewModel即 Model of View)它即包含了Modle也有View的狀態。
MVVM模式中,一個ViewModel和一個View匹配,它沒有MVP中的IView接口,而是徹底的和View綁定,全部View中的修改變化,都會自動更新到ViewModel中,同時ViewModel的任何變化也會自動同步到View上顯示。
這種自動同步的緣由其實就是是ViewModel中的屬性都實現了observable這樣的接口,也就是說當使用屬性的set的方法,都會同時觸發屬性修改的事件,使綁定的UI自動刷新。
在android中DataBinding幫助咱們實現MVVM,在XML進行數據綁定,增長了XML的重量,再也不像之前那樣僅僅是佈局,均衡了各部分的職責。
因此MVVM比MVP更升級一步,在MVP中,V是接口IView, 解決對於界面UI的耦合; 而MVVM乾脆直接使用ViewModel和UI無縫結合, ViewModel直接就能表明UI.
一、解決了MVP大量的手動View和Model同步的問題,提供雙向綁定機制。提升了代碼的可維護性。大大方便了開發者。(只有試過才知道有多方便)
二、簡化測試。
三、響應式編程更方便。
一、過於簡單的圖形界面顯得大材小用(讓開發者麻煩的都是缺點)
二、視圖狀態較多,ViewModel的構建和維護的成本都會比較高。
三、數據綁定的聲明是指令式地寫在View的模版當中的,這些內容是沒辦法去打斷點debug的。(這是很碉堡的,只能本身細心了)
進化4.0 CLEAN
進化了一代有一點,做爲東家的谷歌坐不住了,給不給我面子了,來來來,我給大家一個終結的,Clean? WTF?這個洋蔥一個的傢伙是誰?再給你一個圈就是五環了~~四個圈圈了不得啊?
官方的話說來就是:獨立
同心圓表明軟件的不一樣領域。通常來講,你走的越遠,軟件就越高。外圈是機制。內圈是政策。
使這種架構工做的首要規則是依賴規則。此規則代表源代碼依賴項只能指向內部。內圈中沒有任何東西能夠對外圈中的某些東西一無所知。特別是,內圈中的代碼不得說起在外圈中聲明的內容的名稱。這包括功能,類。變量或任何其餘命名的軟件實體。外圈中使用的數據格式不該該被內圈使用,特別是若是這些格式是由外圈中的框架生成的話。咱們不但願外圈中的任何東西影響內圈。
官方的話就是繞,其實就是依賴是能向裏依賴,白話就是內圈向外圈提供服務,好比你去食堂吃飯,選擇不一樣的窗口,對着裏面喊到給我來一份魚香肉絲。你不用管裏面的師傅是否是昨天那一個,也不用管裏面的菜是否是昨天的那個口味,你只管你的目的是來一份魚香肉絲就能夠了,裏面的菜和師傅,也不用管你是誰,是否是個漂亮的MM,他們只管本身事情,對他們圈外的不依賴,反正你依賴我就能夠了。
Clean將核心業務(Domain層)、UI相關(Presenter層)以及數據加載(Data層)彼此獨立開來,不一樣的層之間由接口依次鏈接起來,但卻又彼此不瞭解彼此的具體實現。
一、代碼複用性更高 二、更易於測試 三、耦合度更小
一、學習難度大(容易懵逼) 二、代碼量大(一個小Demo都夠你寫一壺了)
從MVC->MVP->MVVM->MVP-Clean 後者解決了前者遺留的問題,把前者的缺點優化成了優勢。一代更比一代強,可是都是須要代價的,學習成本更高,更加規範,可是並不必定就誰比誰更好,只有誰更適合你的項目,都有優劣,怎麼選擇須要靠本身了。 其實MVX系列的本質一直未變:
同時也但願適度設計,不要太過追求某一點。會得不償失。找到最經濟的方案纔是王道,也能夠多種方案配合一塊兒配合。
如何可以更好的將多種架構表如今一款APP裏面呢?對!組件化。
組件化
組件化開發就是將一個app分紅多個模塊,每一個模塊都是一個組件(Module),開發的過程當中咱們可讓這些組件相互依賴或者單獨調試部分組件等,可是最終發佈的時候是將這些組件合併統一成一個apk,這就是組件化開發。
不一樣的Module咱們根據職責劃分選擇不一樣的架構,能夠最經濟的開發一款APP。
目前成熟的方案有阿里的ARouter,經過路由的方式進行通訊,感興趣的同窗能夠學習下。
一、低耦合 二、能夠針對測試(下降測試成本) 三、複用性強 四、支持並行開發 五、適合使用多進程 六、減少編譯時間
一、不適合小型應用或者獨立開發 二、各組件開發人員聯調,開發進度不一致等問題
假如一個app用戶量很大,業務豐富,好比某寶,很明顯不是一個小團隊能夠開發的了的,若是不分模塊的話,工程的複雜度就太大了,編譯時間估計半天都完不成,維護更不用說了,簡直不是人乾的了。因此很適合分模塊來開發。各個模塊的耦合性也能降到最低,不至於一個模塊有問題,牽連別的模塊。編譯時間也會大大減少。每一個模塊至關於一個小APP,更容易靈活的編譯,編寫。測試也只須要測試本模塊,最後聯調總體就能夠了。因此說業務越複雜,組件化越有優點。
小結
移動端架構的差別化體如今通訊機制上。通訊機制主要分爲3種: 1) 對象持有 2) 接口持有 3) 路由
對象持有最簡單,可是解耦率最低; 接口持有較爲複雜,實現解耦的需求,可是解耦不完全,相互持有交互方的接口; 路由機制能夠實現徹底解耦,實現組件化。
完了嗎?不不不~~移動端不只僅Android和iOS,還有前端,上面僅僅是MVX的進化史,同時還有不一樣分支的進化。
當下移動端的趨勢,愈來愈向大前端靠攏了,Android的道友們也愈來愈瑟瑟發抖,看到RN,Flutter等等的興起,愈來愈以爲僅僅學習Android是不夠的,還要學習跨平臺,大前端的知識。俗話說他山之石能夠攻玉,咱們對架構的思考也是如此,不能僅限於本身的一畝三分地,也要學習下友軍的套路。
這類通常都是響應式視圖的系統,MVVM就是個響應式,因此其實都是有聯繫的。
進化 5.0 Flutter/ReatNative
Flutter 是Google用以幫助開發者在Ios和Android兩個平臺開發高質量原生應用的全新移動UI框架,也是聽說要把Android替換掉的一個恐怖存在(目前如今仍是個弱雞)
ReactNative 讓開發者使用 JavaScript 和 React 編寫應用,利用相同的核心代碼就能夠建立 Web,iOS 和 Android 平臺的原生應用。React Native 的宗旨是,學習一次,高效編寫跨平臺原生應用。
JS 開發者能夠用相似DOM編程模型就能夠開發原生APP,畫UI只須要畫到virtual DOM 中,不須要特別關心具體的平臺, RN 會把應用的JS代碼編譯成一個js文件,RN的總體框架目標就是爲了解釋運行這個js 腳本文件,經過bridge 傳遞到native , 而後根據數據屬性設置各個對應的真實native的View。
RN官方給的框架是Flux:
解耦很細,作一個功能會涉及不少地方,因此人們對於這個官方架構進行簡化,因而有了Reflux。
Reflux:
咱們也能夠參考另一種架構Redux。
Redux:
這就是面向狀態編程
react的組件只關注數據的最終狀態,數據是怎麼產生的並不關心。這個是RN的核心思想。
優勢 一、提高產品迭代速度,APP迭代週期變短 二、減小研發成本(可不,ios和android均可如下崗了) 三、提高開發測試效率(不用雙端兩套代碼分開測試了)
缺點 一、原生有些功能實現不了或者說很複雜 二、須要掌握IOS和Android的知識,我的學習成本高 三、須要兼容IOS和Android(很苦逼)
今年穀歌推出了Flutter的Beta版本,離正式的出生愈來愈近了。咱們來看看這個新同窗吧。
Flutter主要解決了移動開發中的兩個重要問題,一是原生應用程序的性能與平臺的集成;二是提供多平臺、可移植的UI工具包支持高效應用開發。
和RN的跨平臺思想不一樣
RN是將一種設計理念延伸到兩個平臺,而Flutter則實現了一套代碼,部署多個平臺。解決了RN開發須要IOS和Android基礎的窘迫和成本。在Flutter中,每一個應用程序都是Widget,這點和其餘的應用框架不同,Flutter的對象模型是統一的,也就是控件。
Flutter 基本上就是一個 V(View),響應式視圖,它能夠是無狀態或有狀態的 widget,就連 AppCompatActivity 也是一個 widget。是否是很過度?簡單到粗暴。採用widget 和 state分離 ,好比咱們在原生裏大量重複代碼來管理 Activity 的生命週期。可是在 Flutter 中,這是不須要的,從設計的角度就解決了這個問題。就像LifeCycles也是這種思想,解決了生命週期的問題。
對於這種面向狀態編程的思想,架構和RN是相似,同時咱們也期待Google的官方架構指導的出現,會不會有更多的驚喜呢?
缺點 一、包體很大須要打包本身的SDK 二、佔用內存空間大 三、啓動時間很慢 四、流暢性和原生有差距
不過由於FLutter還沒與正式出版,相信FLutter會解決這些缺點的。
對於這二者系統架構的區別 這裏有兩張圖:
實現跨平臺的這兩種方式也是架構設計的體現,Bridge有沒有和Presenter很類似,鏈接着js和系統。RN是將一種設計理念延伸到兩個平臺,而Flutter則實現了一套代碼,部署多個平臺。
不一樣的設計思想,會走向不一樣的路,究竟是哪種走的更好,這個可能就須要隨着時間去檢驗了,雖然理論上FLutter要比RN好不少,可是如今的顯示很殘酷。不過FLutter纔是Beta版本,潛力很是大。
寫在最後
本文把目前移動端主流的架構順了一遍,也是我本身對架構認識的一個時間軸,從剛開始的胡亂編寫,到後來有些章法,不過仍是對框架的領悟很淺,確定有不少謬論錯輪,但願以我我的對架構的思考能夠拋磚引玉,若是能夠給你一些幫助,那是極好的一件事情了。
無論是RN仍是Flutter,亦或是原生的IOS和Android,其實他們本質編程思想是一致,一樣,隨着更多更方便的框架出來,咱們的理解能力和學習能力受到了很大的挑戰,不少同窗都說學不動,可是事實上技術的更新換代遠比咱們學習新知識要快,每每咱們剛學會這個,又會出了另一個,咱們只要掌握了它的核心思想,就不會那麼累和無奈了。
這就是技和道的差異,經過技最終掌握道,而不是以技學技,那樣沒有終點。
咱們在實際中如何選擇架構,其實這個的因素不少,最關鍵的是一個經濟,好比項目時間比較短,仍是獨立開發,咱們可能就要用MVC了,或者說應用的功能相對簡單,也會取用MVC,至於MVP,或者MVVM,CLEAN,這個對於大型開發,特別是協做開發,有着很大的幫助。由於咱們工做不只僅是技術,還有項目週期,老闆的喜愛,歷史遺留問題,因此選擇最經濟的一個,而不是選擇那個公認最好的那個。
移動端的趨勢愈來愈走向統一了,咱們發現愈來愈多的公司,須要大前端的人才,因此要一直學習,創造時代的人都沒有說累,咱們跟着學習的人更不該該喊累,沒有學不動,只有不想學。同時歡迎你們來剛哥的知識星球,一塊兒激勵,一塊兒砥礪前行。
參考:
React Native運行原理解析 https://blog.csdn.net/xiangzhihong8/article/details/52623852
React Native vs. Flutter 評測 https://mp.weixin.qq.com/s/Or28Gf71wuJrCUP0lKGpGg
ReactNative的組件架構設計 http://react-china.org/t/reactnative/3486
爲安卓開發者介紹的移動開發框架 Flutter https://blog.csdn.net/Px01Ih8/article/details/79683595