移動端開發:架構那點事!

此前,58 同城的技術委員會執行主席沈劍在 OneAPM 的技術公開課上分享過一個主題,「好的架構不是設計出來的,而是演技出來的」。由於對不少創業公司而言,隨着業務的發展,網站流量或者移動端用戶都會經歷不一樣的階段。前期的時候,很難去設計一個百萬或者千萬級併發的架構,因此後期每每不斷對架構進行更新迭代。java

固然,在這裏也推薦一篇文章《移動開發中的痛點》,本文是 infoQ 舉辦線下聚會的一次討論整理,當時參與的討論者包括唐巧、郭亮、郭虹宇、鄧宇光、代碼家等國內知名移動開發者。其中就談及了 MVC 架構的痛點,以及 React Native 所表明的 Web 開發 Native App 技術,相信會對你們有所啓發。移動精英開發社羣的第8期,也是圍繞「架構」這個話題進行討論。本文系滴滴出行的劉佳達整理。ios

如下爲討論內容整理:web

主持人韓兵:「架構」對開發者而言就是「高大上」,固然也不是每位 coder 都能搞定。對不少菜鳥而言就更陌生了,基本只能停留在理論層次。實踐才能出真知,一個好的架構也是這樣產生的。本次咱們但願結合實際開發中遇到的問題,來聊聊移動端的架構設計。shell

李文傑:咱們的項目劃分紅了:數據層、UI 層、邏輯層。編程

上海-李博:咱們使用的是 MVVM(Model-View-ViewModel),而後使用了一些 React Native。設計模式

韓兵:MVC 這樣的模式能夠代替我們移動端架構嗎?數組

攻城獅:MVC、MVVM 只是一種設計模式而已。瀏覽器

Wallace:我的認爲, MVC 這種經典結構已經知足不了如今的需求了。緩存

Rory:MVC 這樣的模式改進一些,可能會更適合移動端架構。從業務邏輯的角度看,架構應該服從業務邏輯。安全

王威特-明道-ios:基於團隊、服務於團隊的代碼基礎規範包含開發模式,代碼規範等等。

Draven-ios:我認爲,MVVM + React Native 能讓開發變得輕鬆不少。

李文傑-上海數雲-ios:特別但願有一套成熟的架構,UI 和邏輯都寫好了。只要寫寫數據就能夠用了。我針對的是超快速的簡單需求 APP 開發,就像不少建站技術同樣,「拖一拖」就能夠完成。

攻城獅:功能模塊化也是架構中很重要的一環。

小龍:萬變不離其宗,天下武功出一家! 移動端各路設計不也是圍繞着 MVC 控制顯示數據,而後再作各類拆分嗎?

露露:模塊與模塊之間,應該能快速拆分而後移植到新的項目中吧?

蜂鳥:用 React 基於響應式函數編程是能夠簡化實現過程,省不少代碼。

劉玉嬌-小鄰小裏-ios:問下你們網絡層搭建用的是 delegate 仍是 block ?咱們後來用的,發現好像 delegate 會好一點。

Draven-ios:block 比較靈活。

王宇-陸金所-ios:可是 block 寫的太隨意了。

Draven-ios:delegate 看起來比較規範。

小龍:block 是方便,但別忘了它是一個結構體。

蜂鳥:昨天碰到一個問題,就是一個 App 有100多我的共同開發,怎麼設計架構?才能讓100我的協同開發不出問題?

A-困惑:通常用 block。

Icocos:以前有人討論過,說用 MVP 比較好。

小龍:若是東西多了很重的,delegate 傳的時候只是一個指針。

進擊的小比克:一部分作網絡層,一部分作業務邏輯,一部分作 UI。

王威特-明道-ios:delegate 書寫規範,也能夠避免循環引用的問題。block 書寫流暢,可是會把網絡的代碼分散在各處,最終維護不必定好。建議在網絡業務種的結構內用 delegate,反之block更方便。

露露:若是幾個實例用一個 delegate,須要判斷。

上海-李博:我以爲,進行工程性的管理,仍是比較好。各作各的業務,淘寶就是採用這種模式。至關於每一個業務維護一個工程。

潘衛傑:可使用插座式的模塊開發。分紅多個小 Team ,負責相對獨立的業務功能開發,每一個 Team 配一個測試,經過了就提交,隨時能夠打包出成品。

韓兵:以前也有人說了,架構是不只僅是爲了方便業務,還有一個是爲了咱們 coder 快速開發。那架構解決了咱們項目開發中的什麼問題?

露露:如今 block 用的不少,可是怎麼纔算使用的好呢?

小龍:delegate 是指針,block 是結構體,一個傳遞的時候輕,但寫着麻煩,一個寫着方便傳遞的時候比較重。

潘衛傑:以前咱們公司移動端的大項目就是「插座式」開發的,批量出各個行業的 App。

Rory:移動架構設計和選型根據個人經驗應該遵照如下幾個原則吧:

  1. 優先保證業務邏輯;
  2. 架構設計遵循簡潔的原則;
  3. 架構的學習成本不要過高,須要符合當前技術團隊內開發人員的能力範圍;
  4. 架構是在開發過程當中不斷擴充和維護的,代碼重構也是架構的核心之一。

劉玉嬌:還有個問題,你們 VC 的分層是 base 而後下邊分爲 baselist 和 baseentity 而後往下繼承嗎?

上海-李博:我感受上面說的繼承這樣下去會愈來愈痛苦

潘衛傑:前年的時候,行業內有一個說法:各個行業扁平化,去中心化,不少行業老闆也都想有本身的電子商務平臺。咱們以前就給他們解決這個問題,可是咱們又不能每家都出一個,就用這種方式出一個不少功能的,各家用的時候在後臺自定義組合。

小龍:高內聚低耦合!

Noark9:之前公司作一個 Windows 上應用的以爲思路能夠借鑑:咱們有一個比較大的,咱們稱爲 shell(殼程序),而後,殼程序提供了接口請求的框架,用戶信息的接口,發送通知,以及一些公共的功能。而後,每一個小功能,都做爲一個動態庫接入,殼程序負責加載下載下來的動態庫,而後打開到界面上。

王宇-陸金所-ios:具體怎麼和業務模塊拆分方法呢?

韓兵:服務端都是重架構,通常移動端都偏輕架構。

王威特:是,繼承的耦合性過重。用組合的方式更好,前幾天的一篇文章就很是推薦閱讀。

http://blog.yongfengzhang.com/cn/blog/write-code-that-is-easy-to-delete-not-easy-to/

Rory:理論上,架構不必定要多複雜。可是至少簡明的能夠區分組件、組件的邏輯、業務邏輯、數據層。讓組件的邏輯和業務邏輯分離,減小代碼耦合;方法的適量重載和重寫;在項目的維護期,抽離項目特有的組件。

蜂鳥:具體到寫代碼,就是多用接口,定義個協議來實現後使用它。

小龍:面向協議就是看接口定義的怎麼樣了。能夠把各行業一些特性歸類爲某一類屬性,統一處理,最後用的時候換個皮,換套文案就能夠。

蜂鳥:API 接口定義的好,說明模塊分離,邊界定義的很清楚。

小龍:面向協議的變成是否是給 ViewController 暴露的都是 id <某個協議> ?這種形式的,而不須要 import 具體的類?求解答。

你該休息了:Android 架構中熱部署你們常採用的多嗎 ?

李哲-京東:我重寫的時候,就遵循的就是各個模塊的拆分。將業務,功能,包括很小的通知名,顏色,緩存路徑都搞成了宏定義。將網絡,數據,業務,功能都剝離了出來。

王威特:宏定義寫起來有些難堪,用 const string 不是更好嗎?

韓兵:能夠推薦一些架構設計比較好的來源代碼

阿塵:我的感受,要深刻移動架構,必須瞭解企業應用架構。開源的完整 App 應該比較少。爲何要有架構?根本緣由仍是在於複雜性。頭一次看到就五體投地,以前用 NimbusKit 搭架構,如今打算轉向 YYKit 。簡單的 App 是不須要架構的。

李哲:將一些業務的解決方法,使用模型思想去解決,尤爲是那個微博列表的設計。要寫易刪除,而不易擴展的代碼。

阿塵:我的感受,合理的分層設計很關鍵。

哈哈:好比微信 SDK,集成了登陸、分享、支付三個大的功能,不支持單獨拆分使用,若是以前已經使用了友盟、shareSDK 等,只想接入微信支付功能,就會出現衝突問題。

阿塵:架構的構建是一個不斷權衡的過程。

有一個道理:架構的構建是一個不斷權衡的過程?這個有點不一樣意。

蜂鳥:我以爲架構之因此須要,就是要保持一個基本的穩定架構,別變來變去的。再變也是細節和模塊功能的補充,跳不出已經設定好的架構。

韓兵:好的東西都不是不斷改,不斷優化的。

小龍:響應式編程思想:不須要考慮調用順序,只須要知道考慮結果,相似於蝴蝶效應,產生一個事件,會影響不少東西,這些事件像流同樣的傳播出去,而後影響結果,借用面向對象的一句話,萬物皆是流。

而函數式編程思想是把操做盡可能寫成一系列嵌套的函數或者方法調用。函數式編程特色:每一個方法必須有返回值(自己對象),把函數或者 Block 當作參數,block 參數(須要操做的值)block 返回值(操做結果)。

表明:ReactiveCocoa。

李哲-京東:而一個好的架構也老是在業務不斷變化中慢慢變好的。

小龍:鏈式編程思想:是將多個操做(多行代碼)經過點號(.)連接在一塊兒成爲一句代碼,使代碼可讀性好。a(1).b(2).c(3)

鏈式編程特色:方法的返回值是 block,block 必須有返回值(自己對象),block 參數(須要操做的值)

表明:masonry 框架。

蜂鳥:若是架構老是變來變去,偏偏證實了架構設計的不合理。

攻城獅:如今好多大公司有個技術平臺部,把一些功能抽象出來模塊化,這樣業務線開發就簡單不少,效率也高了。

阿塵:架構是一組決策的組合,作每一個決策的過程都是一次取捨和權衡,這樣理解嗎?我以爲,實踐出真知,從0開始打造一個複雜 App 的過程,會讓你受益不淺。

王威特:這回到主持人說的,架構是經驗積累出來的,慢慢來。即便作了一個壞架構,之後和別人的對比下就收穫頗豐了。

攻城獅:架構不是一下就有的,走過才知道捷徑。

蜂鳥:贊成你說的決策的取捨平衡,個人見解是這種決策取捨越少越好。好的架構應該能有空間適應這種業務的變化,預見到也許會有的改動,有點理想化了。

王威特:一個長期迭代的 App 作的就是架構和業務,架構能力也是慢慢磨出來的。若是在外包公司工做,更要作好架構,才能快速開發。

攻城獅:有些公司 iOS 頁面跳轉是統一的一個管理類來管理的,在座各位有這麼作的嗎?

進擊的小比克:如今的項目既按功能模塊分,又分業務邏輯、網絡層、數據層,分得有點亂啊!和網絡服務器框架同樣。

高山:好比一個頁面,須要 abcd 四個頁面才能過來,如今一個 url ,不少前置條件都沒有,可能致使錯誤。這就對架構解耦提出更高的要求。

王威特:最先 ABRouter ,你給 viewController 寫個 category 就好了。這裏說的是iOS,用 router 實現跳轉,一個極大的極大的便利就是之後你的 App 須要實現從 safari 瀏覽器打開 App ,發現你都搞定了。

韓兵:好像我們討論組作服務端的人很少。什麼是服務端架構?服務端涉及的東西太多。只有親自設計過和處理過數量級比較大的系統,纔可能會對架構有所體悟。要否則極可能是「紙上談兵」。

Wallace:其實好的架構,無非是能在你現有的狀況下,能解決實際中存在的問題。有些很牛逼的架構不必定適用於如今的具體場景。

韓兵:自己架構包含的知識就不少,不只僅一門編程語言。

攻城獅:Java 比較成熟,可是提供的架構還有一些並非很成熟。

檸檬:從頭看了下,都是偏於理論,對於架構仍是沒什麼印象,好比說 MVC,這也是最基本的。可是如何作到架構師級別?求指教。

檸檬:最近在整理一些知識,我的感受,想能爲架構師,就是把基本的東西包「打包」在一個項目中。

Wallace:其實寫的時間長了,很天然的就能時刻考慮到「高內聚低耦合」的思惟了。尤爲是,寫完一個模塊後也能夠錘鍊本身。

韓兵:設計一個 App,首先應該考慮的就是它的架構。先把結構搭建起來,網絡層封裝好,第三方控件封裝好,而後最快速度支撐起業務層。其實在實際開發中,沒有那麼多時間成本,仍是須要優化一些東西。

丁建龍:模塊化,最少的暴露參數和接口。

檸檬:目前所面臨的代碼質量問題,絕大部分不是技術問題,不是 coding 能力問題,是節奏把控,是質量觀念的問題,如何平衡 scope 、quality、schedule,這不是自下而上的變革,是自上而下的思想改變,每個技術 leader 都須要去權衡把控。

一切質量問題,本質上就是技術 leader 的問題,不少人可能會說,業務需求太多,工做量太大,跑得太快,這些都是事實,事實的背後是,咱們技術有沒有真正去理解業務,理解產品的思路和想法,理解業務的核心訴求和難點,你們必定能夠平衡好這三方面的關係。

韓兵:你們的項目都是怎麼搭建起來的?

檸檬:咱們是初版確定是快速出原形,看用戶的功能,兩週一個迭代。成型後重構。

Rory:初期:簡易架構,實現基礎功能,組件;開發過程當中:迭代豐富組件,抽離業務,造成模塊化。像初期選型,我能夠用諾遠目前1.0->1.1的版本發展歷程舉個例子。後期維護擴容,能夠用365日曆的 Android 客戶端舉個例子。

韓兵:這個只有實踐過,纔可能會有一些感悟。說說你們 App 從無到有的構建過程。從這個過程當中理解架構的造成和運做。我的以爲從這點入手,會容易理解一些。

檸檬:架構看功力,架構師的路很長,不斷的被指責,改進的過程,這是漫長的過程。我如今的想法是把幾乎全部項目都用到的東西,整理在一個項目下,之後獨立開發能夠直接運用。還能夠把整個項目底層作一個基類。

Rory:目前互聯網行業主要仍是敏捷開發,因此初期選型的時候,其實架構細分顯得不是很重要,卻是架構上爲後期模塊化,可擴展性的方面考慮更多。好比,小諾理財 Android 客戶端,初期架構只作了網絡層,數據解析,activity 基類封裝,圖片緩存,和一些經常使用的 UI 組件。

露露:我以爲你能夠整合,可是若是用了某一個功能,能快速拆分。

Wallace:我曾經最開始工做的時候,覺得把見過的東西都存下來,到時候用上,但其實都沒用上。

Rory:總體上業務結構初期都是在 Activity 中處理的,沒有作業務邏輯的抽離。從1.0-1.1的過程當中,這邊的 Android 技術團隊進行了一些重構和業務抽離,構建基礎。造成目前定製的 UI組件庫(目前 UI 組件的邏輯仍然未進行細緻抽離)、業務邏輯 control 單元(目前是依據業務模塊的不一樣,抽離不一樣模塊的 control。)這麼作,主要的目的是爲了後續新加入的技術,能夠快速熟悉項目,瞭解業務。

韓兵:若是這個項目越作越大,我們就暫定理財項目,是否是要考慮底層框架對現有業務的支持?若是團隊愈來愈大,是否是還要考慮對n多個團隊的支持?

Rory:理財和支付同樣,對數據安全和通訊安全比較重視。

阿塵:橫向業務模塊化,豎向低耦合,作到單向依賴。

Rory:曾經參與過,365日曆 Android 客戶端的後期維護。當時客戶端項目到了後期,模塊劃分會愈來愈多,項目會變得愈來愈臃腫。這時候在 java 層面和 Android framework 層的優化其實更少。

多數組件這時候都已經很成熟,這時候須要集成性能測試,針對某一點上進行細節優化。架構上也是抽離出更多的庫,進行細分支持。365日曆實際上是典型的 MVC 向 MVP 的過渡。固然,我離職的時候這個過渡還未完成。基本上雛形能夠看到,UI 層和業務層已經進行深度劃分,經過 control 控制數據傳遞和通訊。

MVP,我的經驗更適合移動端,移動端開發的主要難點是兩個,業務邏輯和界面效果。

韓兵:因此移動端和服務端考慮的點也是不同的!

Rory:把 UI 和業務邏輯區分,這樣控制單元更有針對性,對原有業務或者UI的修改更有針對性,迭代過程當中產生錯誤理解和錯誤邏輯致使 bug 的可能性也更小。

可能由於這樣抽離後,新技術的加入,理解項目須要更長的時間。代碼閱讀性會隨着項目的臃腫變得愈來愈差。因此必要的抽離就是保證代碼的可讀性。

過渡重構舉個很簡單的例子,一個 View 的 UI 邏輯非要強行適應整個項目全部的 View,創造 n 個構造,傳入多個控制參數。那麼邏輯理解起來是否是很困難?最簡單的斷定標準,代碼的創造者若是隔一段時間都很難讀得懂本身寫的代碼,算不算一種過分?

簡單的總結下,架構應該隨着項目發展不斷髮展,一成不變的架構是行不通的!

移動端開發:架構那點事!

國內 ITOM 管理平臺 OneAPM 致力於幫助企業用戶提供全棧式的性能管理以及 IT 運維管理服務,經過一個探針就可以完成日誌分析、安全防禦、APM 基礎組件監控、集成報警以及大數據分析等功能。想閱讀更多優秀文章,請訪問 OneAPM 官方技術博客
本文轉自 OneAPM 官方博客

相關文章
相關標籤/搜索