精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

iOS應(yīng)用架構(gòu)談第一篇 開篇

移動開發(fā) iOS
之前安居客iOS app的第二版架構(gòu)大部分內(nèi)容是我做的,期間有總結(jié)了一些經(jīng)驗。在將近一年之后,前同事zzz在微信朋友圈上發(fā)了一個問題:假如問你一個iOS or Android app的架構(gòu),你會從哪些方面來說呢?

iOS應(yīng)用架構(gòu)談 開篇

iOS應(yīng)用架構(gòu)談 view層的組織和調(diào)用方案

iOS應(yīng)用架構(gòu)談 網(wǎng)絡(luò)層設(shè)計方案

iOS應(yīng)用架構(gòu)談 動態(tài)部署方案

iOS應(yīng)用架構(gòu)談 本地持久化方案

緣由

之前安居客iOS app的第二版架構(gòu)大部分內(nèi)容是我做的,期間有總結(jié)了一些經(jīng)驗。在將近一年之后,前同事zzz在微信朋友圈上發(fā)了一個問題:假如問你一個iOS or Android app的架構(gòu),你會從哪些方面來說呢?

當時看到這個問題正好在乘公車回家的路上,閑來無聊就答了一把。在zzz在微信朋友圈上追問了幾個問題之后,我覺得有必要開個博客專門來講講一些個人見解。

其實對于iOS客戶端應(yīng)用的架構(gòu)來說,復雜度不亞于服務(wù)端,但側(cè)重點和入手點卻跟服務(wù)端不太一樣。比如客戶端應(yīng)用就不需要考慮類似C10K的問題,正常的app就根本不需要考慮。

這系列文章我會主要專注在iOS應(yīng)用架構(gòu)方面,很多方案也是基于iOS技術(shù)棧的特點而建立的。因為我個人不是很喜歡寫Java,所以Android這邊的我就不太了解了。如果你是Android開發(fā)者,你可以側(cè)重看我提出的一些架構(gòu)思想,畢竟不管做什么,思路是相通的,實現(xiàn)手段不同罷了。

當我們討論客戶端應(yīng)用架構(gòu)的時候,我們在討論什么?

其實市面上大部分應(yīng)用不外乎就是顛過來倒過去地做以下這些事情:

簡單來說就是調(diào)API,展示頁面,然后跳轉(zhuǎn)到別的地方再調(diào)API,再展示頁面。

那這特么有毛好架構(gòu)的?

非也,非也。 ---- 包不同 《天龍八部》

App確實就是主要做這些事情,但是支撐這些事情的基礎(chǔ),就是做架構(gòu)要考慮的事情。

調(diào)用網(wǎng)絡(luò)API

頁面展示

數(shù)據(jù)的本地持久化

動態(tài)部署方案

上面這四大點,稍微細說一下就是:

如何讓業(yè)務(wù)開發(fā)工程師方便安全地調(diào)用網(wǎng)絡(luò)API?然后盡可能保證用戶在各種網(wǎng)絡(luò)環(huán)境下都能有良好的體驗?

頁面如何組織,才能盡可能降低業(yè)務(wù)方代碼的耦合度?盡可能降低業(yè)務(wù)方開發(fā)界面的復雜度,提高他們的效率?

當數(shù)據(jù)有在本地存取的需求的時候,如何能夠保證數(shù)據(jù)在本地的合理安排?如何盡可能地減小性能消耗?

iOS應(yīng)用有審核周期,如何能夠通過不發(fā)版本的方式展示新的內(nèi)容給用戶?如何修復緊急bug?

上面幾點是針對App說的,下面還有一些是針對團隊說的:

收集用戶數(shù)據(jù),給產(chǎn)品和運營提供參考

合理地組織各業(yè)務(wù)方開發(fā)的業(yè)務(wù)模塊,以及相關(guān)基礎(chǔ)模塊

每日app的自動打包,提供給QA工程師的測試工具

一時半會兒我還是只能想到上面這三點,事實上應(yīng)該還會有很多,想不起來了。

所以當我們討論客戶端應(yīng)用架構(gòu)的時候,我們討論的差不多就是這些問題。

這系列文章要回答那些問題?

這系列文章主要是回答以下這些問題:

網(wǎng)絡(luò)層設(shè)計方案?設(shè)計網(wǎng)絡(luò)層時要考慮哪些問題?對網(wǎng)絡(luò)層做優(yōu)化的時候,可以從哪些地方入手?

頁面的展示、調(diào)用和組織都有哪些設(shè)計方案?我們做這些方案的時候都要考慮哪些問題?

本地持久化層的設(shè)計方案都有哪些?優(yōu)劣勢都是什么?不同方案間要注意的問題分別都是什么?

要實現(xiàn)動態(tài)部署,都有哪些方案?不同方案之間的優(yōu)劣點,他們的側(cè)重點?

本文要回答那些問題?

上面細分出來的四個問題,我會分別在四篇文章里面寫。那么這篇文章就是來講一些通識啥的,也是開個坑給大家討論通識問題的。

架構(gòu)設(shè)計的方法

所有事情最難的時候都是開始做的時候,當你開始著手設(shè)計并實現(xiàn)某一層的架構(gòu)乃至整個app的架構(gòu)的時候,很有可能會出現(xiàn)暫時的無從下手的情況。以下方法論是我這些年總結(jié)出來的經(jīng)驗,每個架構(gòu)師也一定都有一套自己的方法論,但一樣的是,不管你采用什么方法,全局觀、高度的代碼審美能力、靈活使用各種設(shè)計模式一定都是貫穿其中的。歡迎各位在評論區(qū)討論。

第一步:搞清楚要解決哪些問題,并找到解決這些問題的充要條件。

你必須得清楚你要做什么,業(yè)務(wù)方希望要什么。而不是為了架構(gòu)而架構(gòu),也不是為了體驗新技術(shù)而改架構(gòu)方案。以前是MVC,最近流行MVVM,如果過去的MVC是個好架構(gòu),沒什么特別大的缺陷,就不要推倒然后搞成MVVM。

關(guān)于充要條件我也要說明一下,有的時候系統(tǒng)提供的函數(shù)是需要額外參數(shù)的,比如read函數(shù)。還有翻頁的時候,當前頁碼也是充要條件。但對于業(yè)務(wù)方來說,這些充要條件還能夠再縮減。

比如read,需要給出file descriptor,需要給出buf,需要給出size。但是對于業(yè)務(wù)方來說,充要條件就只要file descriptor就夠了。再比如翻頁,其實業(yè)務(wù)方并不需要記錄當前頁號,你給他暴露一個loadNextPage這樣的方法就夠了。

搞清楚對于業(yè)務(wù)方而言的真正充要條件很重要!這決定了你的架構(gòu)是否足夠易用。另外,傳的參數(shù)越少,耦合度相對而言就越小,你替換模塊或者升級模塊所花的的代價就越小。

第二步:問題分類,分模塊

這個不用多說了吧。

第三步:搞清楚各問題之間的依賴關(guān)系,建立好模塊交流規(guī)范并設(shè)計模塊。

關(guān)鍵在于建立一套統(tǒng)一的交流規(guī)范。這一步很能夠體現(xiàn)架構(gòu)師在軟件方面的價值觀,雖然存在一定程度上的好壞優(yōu)劣(比如胖Model和瘦Model),但既然都是架構(gòu)師了,基本上是不會設(shè)計出明顯很爛的方案的,除非這架構(gòu)師還不夠格。所以這里是架構(gòu)師價值觀輸出的一個窗口,從這一點我們是能夠看出架構(gòu)師的素質(zhì)的。

另外要注意的是,一定是建立一套統(tǒng)一的交流規(guī)范,不是兩套,不是多套。你要堅持你的價值觀,不要搖擺不定。要是搞出各種五花八門的規(guī)范出來,一方面有不切實際的炫技嫌疑,另一方面也會帶來后續(xù)維護的災(zāi)難。

第四步:推演預測一下未來可能的走向,必要時添加新的模塊,記錄更多的基礎(chǔ)數(shù)據(jù)以備未來之需。

很多稱職的架構(gòu)師都會在這時候考慮架構(gòu)未來的走向,以及考慮做完這一輪架構(gòu)之后,接下來要做的事情。一個好的架構(gòu)雖然是功在當代利在千秋的工程,但絕對不是一個一勞永逸的工程。軟件是有生命的,你做出來的架構(gòu)決定了這個軟件它這一生是坎坷還是幸福。

第五步:先解決依賴關(guān)系中最基礎(chǔ)的問題,實現(xiàn)基礎(chǔ)模塊,然后再用基礎(chǔ)模塊堆疊出整個架構(gòu)。

這一步也是驗證你之前的設(shè)計是否合理的一步,隨著這一步的推進,你很有可能會遇到需要對架構(gòu)進行調(diào)整的情況。這個階段一定要吹毛求疵高度負責地去開發(fā),不要得過且過,發(fā)現(xiàn)架構(gòu)有問題就及時調(diào)整。否則以后調(diào)整的成本就非常之大了。

第六步:打點,跑單元測試,跑性能測試,根據(jù)數(shù)據(jù)去優(yōu)化對應(yīng)的地方。

你得用這些數(shù)據(jù)去向你的boss邀功,你也得用這些數(shù)據(jù)去不斷調(diào)整你的架構(gòu)。

總而言之就是要遵循這些原則:自頂向下設(shè)計(1,2,3,4步),自底向下實現(xiàn)(5),先測量,后優(yōu)化(6)。

什么樣的架構(gòu)師是好架構(gòu)師?

每天都在學習,新技術(shù)新思想上手速度快,理解速度快。

做不到這點,你就是碼農(nóng)。

業(yè)務(wù)出身,或者至少非常熟悉公司所處行業(yè)或者本公司的業(yè)務(wù)。

做不到這點,你就是運維。

熟悉軟件工程的各種規(guī)范,踩過無數(shù)坑。不會為了完成需求不擇手段,不推崇quick & dirty。

做不到這點,你比較適合去競爭對手那兒當工程師。

及時承認錯誤,不要覺得承認錯誤會有損你架構(gòu)師的身份。

做不到這點,公關(guān)行業(yè)比較適合你。

不為了炫技而炫技

做不到這點,你就是高中編程愛好者。

精益求精

做不到這點,(我想了好久,但我還是不知道你適合去干什么。)

什么樣的架構(gòu)叫好架構(gòu)?

代碼整齊,分類明確,沒有common,沒有core

不用文檔,或很少文檔,就能讓業(yè)務(wù)方上手

思路和方法要統(tǒng)一,盡量不要多元

沒有橫向依賴,萬不得已不出現(xiàn)跨層訪問

對業(yè)務(wù)方該限制的地方有限制,該靈活的地方要給業(yè)務(wù)方創(chuàng)造靈活實現(xiàn)的條件

易測試,易拓展

保持一定量的超前性

接口少,接口參數(shù)少

高性能

以上是我判斷一個架構(gòu)是不是好架構(gòu)的標準,這是根據(jù)重要性來排列的。客戶端架構(gòu)跟服務(wù)端架構(gòu)要考慮的問題和側(cè)重點是有一些區(qū)別的。下面我會針對每一點詳細講解一下:

代碼整齊,分類明確,沒有common,沒有core

代碼整齊是每一個工程師的基本素質(zhì),先不說你搞定這個問題的方案有多好,解決速度有多快,如果代碼不整齊,一切都白搭。因為你的代碼是要給別人看的,你自己也要看。如果哪一天架構(gòu)有修改,正好改到這個地方,你很容易自己都看不懂。另外,破窗理論提醒我們,如果代碼不整齊分類不明確,整個架構(gòu)會隨著一次一次的拓展而越來越混亂。

分類明確的字面意思大家一定都了解,但還有一個另外的意思,那就是:不要讓一個類或者一個模塊做兩種不同的事情。如果有類或某模塊做了兩種不同的事情,一方面不適合未來拓展,另一方面也會造成分類困難。

不要搞Common,Core這些東西。每家公司的架構(gòu)代碼庫里面,最惡心的一定是這兩個名字命名的文件夾,我這么說一定不會錯。不要開Common,Core這樣的文件夾,開了之后后來者一定會把這個地方搞得一團糟,最終變成Common也不Common,Core也不Core。要記住,架構(gòu)是不斷成長的,是會不斷變化的。不是每次成長每次變化,都是由你去實現(xiàn)的。如果真有什么東西特別小,那就索性為了他單獨開辟一個模塊就好了,小就小點,關(guān)鍵是要有序。

不用文檔,或很少文檔,就能讓業(yè)務(wù)方上手。

誰特么會去看文檔啊,業(yè)務(wù)方他們已經(jīng)被產(chǎn)品經(jīng)理逼得很忙了。所以你要盡可能讓你的API名字可讀性強,對于iOS來說,objc這門語言的特性把這個做到了極致,函數(shù)名長就長一點,不要緊。

 

思路和方法要統(tǒng)一,盡量不要多元。

解決一個問題會有很多種方案,但是一旦確定了一種方案,就不要在另一個地方采用別的方案了。也就是做架構(gòu)的時候,你得時刻記住當初你決定要處理這樣類型的問題的方案是什么,以及你的初衷是什么,不要搖擺不定。

另外,你當初設(shè)立這個模塊一定是有想法有原因的,要記錄下你的解決思路,不要到時候換個地方你又靈光一現(xiàn)啥的,引入了其他方案,從而導致異構(gòu)。

要是一個框架里面解決同一種類似的問題有各種五花八門的方法或者類,我覺得做這個架構(gòu)的架構(gòu)師一定是自己都沒想清楚就開始搞了。

沒有橫向依賴,萬不得已不出現(xiàn)跨層訪問。

沒有橫向依賴是很重要的,這決定了你將來要對這個架構(gòu)做修補所需要的成本有多大。要做到?jīng)]有橫向依賴,這是很考驗架構(gòu)師的模塊分類能力和是否熟悉業(yè)務(wù)的。

跨層訪問是指數(shù)據(jù)流向了跟自己沒有對接關(guān)系的模塊。有的時候跨層訪問是不可避免的,比如網(wǎng)絡(luò)底層里面信號從2G變成了3G變成了4G,這是有可能需要跨層通知到View的。但這種情況不多,一旦出現(xiàn)就要想盡一切辦法在本層搞定或者交給上層或者下層搞定,盡量不要出現(xiàn)跨層的情況。跨層訪問同樣也會增加耦合度,當某一層需要整體替換的時候,牽涉面就會很大。

對業(yè)務(wù)方該限制的地方有限制,該靈活的地方要給業(yè)務(wù)方創(chuàng)造靈活實現(xiàn)的條件。

把這點做好,很依賴于架構(gòu)師的經(jīng)驗。架構(gòu)師必須要有能力區(qū)分哪些情況需要限制靈活性,哪些情況需要創(chuàng)造靈活性。比如對于Core Data技術(shù)棧來說,ManagedObject理論上是可以出現(xiàn)在任何地方的,那就意味著任何地方都可以修改ManagedObject,這就導致ManagedObjectContext在同步修改的時候把各種不同來源的修改同步進去。這時候就需要限制靈活性,只對外公開一個修改接口,不暴露任何ManagedObject在外面。

如果是設(shè)計一個ABTest相關(guān)的API的時候,我們又希望增加它的靈活性。使得業(yè)務(wù)方不光可以通過Target-Action的模式實現(xiàn)ABtest,也要可以通過Block的方式實現(xiàn)ABTest,要盡可能滿足靈活性,減少業(yè)務(wù)方的使用成本。

易測試易拓展

老生常談,要實現(xiàn)易測試易拓展,那就要提高模塊化程度,盡可能減少依賴關(guān)系,便于mock。另外,如果是高度模塊化的架構(gòu),拓展起來將會是一件非常容易的事情。

保持一定量的超前性

這一點能看出架構(gòu)師是否關(guān)注行業(yè)動態(tài),是否能準確把握技術(shù)走向。保持適度的技術(shù)上的超前性,能夠使得你的架構(gòu)更新變得相對輕松。

另外,這里的超前性也不光是技術(shù)上的,還有產(chǎn)品上的。誰說架構(gòu)師就不需要跟產(chǎn)品經(jīng)理打交道了,沒事多跟產(chǎn)品經(jīng)理聊聊天,聽聽他對產(chǎn)品未來走向的暢想,你就可以在合理的地方為他的暢想留一條路子。同時,在創(chuàng)業(yè)公司的環(huán)境下,很多產(chǎn)品需求其實只是為了趕產(chǎn)品進度而產(chǎn)生的妥協(xié)方案,最后還是會轉(zhuǎn)到正軌的。這時候業(yè)務(wù)方可以不實現(xiàn)轉(zhuǎn)到正規(guī)的方案,但是架構(gòu)這邊,是一定要為這種可預知的改變做準備的。

接口少,接口參數(shù)少

越少的接口越少的參數(shù),就能越降低業(yè)務(wù)方的使用成本。當然,充要條件還是要滿足的,如何在滿足充要條件的情況下盡可能地減少接口和參數(shù)數(shù)量,這就能看出架構(gòu)師的功力有多深厚了。

高性能

為什么高性能排在最后一位?

高性能非常重要,但是在客戶端架構(gòu)中,它不是第一考慮因素。原因有下:

1.客戶端業(yè)務(wù)變化非常之快,做架構(gòu)時首要考慮因素應(yīng)當是便于業(yè)務(wù)方快速滿足產(chǎn)品需求,因此需要盡可能提供簡單易用效果好的接口給業(yè)務(wù)方,而不是提供高性能的接口給業(yè)務(wù)方。

2.蘋果平臺的性能非常之棒,正常情況下很少會出現(xiàn)由于性能不夠?qū)е碌挠脩趔w驗問題。

3.蘋果平臺的優(yōu)化手段相對有限,甚至于有些時候即便動用了無所不用其極的手段乃至不擇手段犧牲了穩(wěn)定性,性能提高很有可能也只不過是100ms到90ms的差距。10%的性能提升對于服務(wù)端來說很不錯了,因為服務(wù)端動不動就是幾十萬上百萬的訪問量,幾十萬上百萬個10ms是很可觀的。但是對于客戶端的用戶來說,他無法感知這10ms的差別,如果從10s優(yōu)化成9s用戶還是有一定感知的,但是100ms變90ms,我覺得吧,還是別折騰了。

但是!不重要不代表用不著去做,關(guān)于性能優(yōu)化的東西,我會對應(yīng)放到各系列文章里面去。比如網(wǎng)絡(luò)層優(yōu)化,那就會在網(wǎng)絡(luò)層方案的那篇文章里面去寫,對應(yīng)每層架構(gòu)都有每層架構(gòu)的不同優(yōu)化方案,我都會在各自文章里面一一細說。

 關(guān)于架構(gòu)分層?

昨晚上志豪看了這篇文章之后說,看到你這個題目本來我是期望看到關(guān)于架構(gòu)分層相關(guān)的東西的,但是你沒寫。

嗯,確實沒寫,當時沒寫的原因是感覺這個沒什么好寫的。前面談?wù)摰郊軜?gòu)的方法的時候,關(guān)于問題分類分模塊這一步時,架構(gòu)分層也屬于這一部分,給我一筆帶過了。

既然志豪提出來了這個問題,我想可能大家關(guān)于這個也會有一些想法和問題,那么我就在這兒講講吧。

其實分層這種東西,真沒啥技術(shù)含量,全憑架構(gòu)師的經(jīng)驗和素質(zhì)。

我們常見的分層架構(gòu),有三層架構(gòu)的:展現(xiàn)層、業(yè)務(wù)層、數(shù)據(jù)層。也有四層架構(gòu)的:展現(xiàn)層、業(yè)務(wù)層、網(wǎng)絡(luò)層、本地數(shù)據(jù)層。這里說三層、四層,跟TCP/IP所謂的五層或者七層不是同一種概念。再具體說就是:你這個架構(gòu)在邏輯上是幾層那就幾層,具體每一層叫什么,做什么,沒有特定的規(guī)范。這主要是針對模塊分類而言的。

也有說MVC架構(gòu),MVVM架構(gòu)的,這種層次劃分,主要是針對數(shù)據(jù)流動的方向而言的。

在實際情況中,針對數(shù)據(jù)流動方向做的設(shè)計和針對模塊分類做的設(shè)計是會放在一起的,也就是說,一個MVC架構(gòu)可以是四層:展現(xiàn)層、業(yè)務(wù)層、網(wǎng)絡(luò)層、本地數(shù)據(jù)層。

那么,為什么我要說這個?

大概在五六年前,業(yè)界很流行三層架構(gòu)這個術(shù)語。然后各種文檔資料漫天的三層架構(gòu),并且喜歡把它與MVC放在一起說,MVC三層架構(gòu)/三層架構(gòu)MVC,以至于很多人就會認為三層架構(gòu)就是MVC,MVC就是三層架構(gòu)。其實不是的。三層架構(gòu)里面其實沒有Controller的概念,而且三層架構(gòu)描述的側(cè)重點是模塊之間的邏輯關(guān)系。MVC有Controller的概念,它描述的側(cè)重點在于數(shù)據(jù)流動方向。

好,為什么流行起來的是三層架構(gòu),而不是四層架構(gòu)或五層架構(gòu)?

因為所有的模塊角色只會有三種:數(shù)據(jù)管理者、數(shù)據(jù)加工者、數(shù)據(jù)展示者,意思也就是,籠統(tǒng)說來,軟件只會有三層,每一層扮演一個角色。其他的第四層第五層,一般都是這三層里面的其中之一分出來的,最后都能歸納進這三層的某一層中去,所以用三層架構(gòu)來描述就比較普遍。

那么我們怎么做分層?

應(yīng)該如何做分層,不是在做架構(gòu)的時候一開始就考慮的問題。雖然我們要按照自頂向下的設(shè)計方式來設(shè)計架構(gòu),但是一般情況下不適合直接從三層開始。一般都是先確定所有要解決的問題,先確定都有哪些模塊,然后再基于這些模塊再往下細化設(shè)計。然后再把這些列出來的問題和模塊做好分類。分類之后不出意外大多數(shù)都是三層。如果發(fā)現(xiàn)某一層特別龐大,那就可以再拆開來變成四層,變成五層。

舉個例子:你要設(shè)計一個即時通訊的服務(wù)端架構(gòu),怎么分層?

記住,不要一上來就把三層架構(gòu)的規(guī)范套上去,這樣做是做不出好架構(gòu)的。

你要先確定都需要解決哪些問題。這里只是舉例子,我隨意列出一點意思意思就好了:

要解決用戶登錄、退出的問題

解決不同用戶間數(shù)據(jù)交流的問題

解決用戶數(shù)據(jù)存儲的問題

如果是多臺服務(wù)器的集群,就要解決用戶連接的尋址問題

解決第一個問題需要一個鏈接管理模塊,鏈接管理模塊一般是通過鏈接池來實現(xiàn)。 解決第二個問題需要有一個數(shù)據(jù)交換模塊,從A接收來的數(shù)據(jù)要給到B,這個事情由這個模塊來做。 解決第三個問題需要有個數(shù)據(jù)庫,如果是服務(wù)于大量用戶,那么就需要一個緩沖區(qū),只有當需要存儲的數(shù)據(jù)達到一定量時才執(zhí)行寫操作。 解決第四個問題可以有幾種解決方案,一個是集群中有那么幾臺服務(wù)器作為尋路服務(wù)器,所有尋路的服務(wù)交給那幾臺去做,那么你需要開發(fā)一個尋路服務(wù)的Daemon。或者用廣播方式尋路,但如果尋路頻次非常高,會造成集群內(nèi)部網(wǎng)絡(luò)負載特別大。這是你要權(quán)衡的地方,目前流行的思路是去中心化,那么要解決網(wǎng)絡(luò)負載的問題,你就可以考慮配置一個緩存。

于是我們有了這些模塊:

鏈接管理、數(shù)據(jù)交換、數(shù)據(jù)庫及其配套模塊、尋路模塊

做到這里還遠遠沒有結(jié)束,你要繼續(xù)針對這四個模塊繼續(xù)往下細分,直到足夠小為止。但是這里只是舉例子,所以就不往下深究了。

另外,我要提醒你的是,直到這時,還是跟幾層架構(gòu)毫無關(guān)系的。當你把所有模塊都找出來之后,就要開始整理你的這些模塊,很有可能架構(gòu)圖就是這樣:

 

 

然后這些模塊分完之后你看一下圖,嗯,1、2、3,一共三層,所以那就是三層架構(gòu)啦。在這里最消耗腦力最考驗架構(gòu)師功力的地方就在于:找到所有需要的模塊, 把模塊放在該放的地方

 

這個例子側(cè)重點在于如何分層,性能優(yōu)化、數(shù)據(jù)交互規(guī)范和包協(xié)議、數(shù)據(jù)采集等其他一系列必要的東西都沒有放進去,但看到這里,相信你應(yīng)該了解架構(gòu)師是怎么對待分層問題的了吧?

對的,答案就是沒有分層。所謂的分層都是出架構(gòu)圖之后的事情了。所以你看別的架構(gòu)師在演講的時候,上來第一句話差不多都是:"這個架構(gòu)分為以下幾層..."。但考慮分層的問題的時機絕對不是一開始就考慮的。另外,模塊一定要把它設(shè)計得獨立性強,這其實是門藝術(shù)活。

另外,這雖然是服務(wù)端架構(gòu),但是思路跟客戶端架構(gòu)是一樣的,側(cè)重點不同罷了。之所以不拿客戶端架構(gòu)舉例子,是因為這方面的客戶端架構(gòu)蘋果已經(jīng)幫你做好了絕大部分事情,沒剩下什么值得說的了。

關(guān)于Common文件夾?

評論區(qū)MatrixHero提到一點:

關(guān)于common文件夾的問題,僅僅是文件夾而已,別無他意。如果后期維護出了代碼混亂可能是因為,和服務(wù)器溝通協(xié)議不統(tǒng)一,或代碼review不及時。應(yīng)該有專人維護公共類。

這是針對我前面提出的不要Common,不要Core而言的,為什么我建議大家不要開Common文件夾?我打算分幾種情況給大家解釋一下。

一般情況下,我們都會有一些屬于這個項目的公共類,比如取定位坐標,比如圖像處理。這些模塊可能非常小,就h和m兩個文件。單獨拎出來成為一個模塊感覺不夠格,但是又不屬于其他任何一個模塊。于是大家很有可能就會把它們放入Common里面,我目前見到的大多數(shù)工程和大多數(shù)文檔里面的代碼都喜歡這么做。在當時來看,這么做看不出什么問題,但關(guān)鍵在于:軟件是有生命,會成長的。當時分出來的小模塊,很有可能會隨著業(yè)務(wù)的成長,逐漸發(fā)展成大模塊,發(fā)展成大模塊后,可以再把它從Common移出來單獨成立一個模塊。這個在理論上是沒有任何問題的,然而在實際操作過程中,工程師在拓張這個小模塊的時候,不太容易會去考慮橫向依賴的問題,因為當時這些模塊都在Common里面,直接進行互相依賴是非常符合直覺的,而且也不算是不遵守規(guī)范。然而要注意的是,這才是Commom代碼混亂的罪魁禍首,Common文件夾縱容了不精心管理依賴的做法。當Common里面的模塊依賴關(guān)系變得復雜,再想要移出來單獨成立一個模塊,就不是當初設(shè)置Common時想的等規(guī)模大了再移除也不遲那么簡單了。

另外,Common有的時候也不僅僅是一個文件夾。

在使用Cocoapods來管理項目庫的時候,Common往往就是一個pod。這個pod里面會有A/B/C/D/E這些函數(shù)集或小模塊。如果要新開一個app或者Demo,勢必會使用到Common這個pod,這么做,往往會把不需要包含的代碼也包含進去,我對項目有高度潔癖,這種情況會讓我覺得非常不舒服。

舉個例子:早年安居客的app還不是集齊所有新房、二手房、租房業(yè)務(wù)的。當你剛開始寫新房這個app的時候,創(chuàng)建了一個Common這個pod,這里面包含了一些對于新房來說比較Common的代碼,也包含了對于這個app來說比較Common的代碼。過了半年或者一年,你要開始二手房這個app,我覺得大多數(shù)人都會選擇讓二手房也包含這個Common,于是這個Common很有可能自己走上另一條發(fā)展的道路。等到了租房這個業(yè)務(wù)要開app的時候,Common已經(jīng)非常之龐大,相信這時候的你也不會去想整理Common的事情了,先把租房搞定,于是Common最終就變成了一坨屎。

就對于上面的例子來說,還有一個要考慮的是,分出來的三個業(yè)務(wù)很有可能會有三個Common,假設(shè)三個Common里面都有公共的功能,交給了三個團隊去打理,如果遇到某個子模塊需要升級,那么三個Common里面的這個子模塊都要去同步升級,這是個很不效率的事情。另外,很有可能三個Common到最后發(fā)展成彼此不兼容,但是代碼相似度非常之高,這個在架構(gòu)上,是屬于分類條理不清。

就在去年年中的時候,安居客決定將三個業(yè)務(wù)歸并到同一個App。好了,如果你是架構(gòu)師,面對這三個Common,你打算怎么辦?要想最快出成果,那就只好忍受代碼冗余,趕緊先把架子搭起來再說,否則你面對的就是剪不斷理還亂的Common。此時Common就已經(jīng)很無奈地變成一坨屎了。這樣的Common,你自己說不定也搞不清楚它里面到底都有些什么了,交給任何一個人去打理,他都不敢做徹底的整理的。

還有就是,Common本身就是一個粒度非常大的模塊。在阿里這樣大規(guī)模的團隊中,即便新開一個業(yè)務(wù),都需要在整個app的環(huán)境下開發(fā),為什么?因為模塊拆分粒度不夠,要想開一個新業(yè)務(wù),必須把其他業(yè)務(wù)的代碼以及依賴全部拉下來,然后再開新入口,你的新業(yè)務(wù)才能進行正常的代碼編寫和調(diào)試。然而你的新業(yè)務(wù)其實只依賴首頁入口、網(wǎng)絡(luò)庫等這幾個小模塊,不需要依賴其他那么多的跟你沒關(guān)系的業(yè)務(wù)。現(xiàn)在每次打開天貓的項目,我都要等個兩三分鐘,這非常之蛋疼。

但是大家真的不知道這個原因嗎?知道了這個原因,為什么沒人去把這些粒度不夠細的模塊整理好?在我看來,這件事沒人敢做。

原來大家用的好好的,手段爛就爛一點,你改了你能保證不出錯?

這么復雜的東西,短期之內(nèi)你肯定搞不好,任務(wù)量和工時都不好估,你leader會覺得你在騙工時玩自己的事情。

就算你搞定了,QA這邊肯定再需要做一次全面的回歸測試,任務(wù)量極大,難以說服他們配合你的工作。

花這么大的成本只是為了減少開啟項目時候等待IDE打開時的那幾分鐘時間?我想如果我是你leader,我也應(yīng)該不會批準你做這樣的事情的。所以,與其到了后面吃這個苦頭,不如一開始做架構(gòu)的時候就不要設(shè)置Common,到后面就能省力很多。架構(gòu)師的工作為什么是功在當代利在千秋,架構(gòu)師的素質(zhì)為什么對團隊這么重要?我覺得這里就是一個最好的體現(xiàn)。

簡而言之,不建議開Common的原因如下:

1.Common不僅僅是一個文件夾,它也會是一個Pod。不管是什么,在Common里面很容易形成錯綜復雜的小模塊依賴,在模塊成長過程中,會縱容工程師不注意依賴的管理,乃至于將來如果要將模塊拆分出去,會非常的困難。

2.Common本身與細粒度模塊設(shè)計的思想背道而馳,屬于一種不合適的偷懶手段,在將來業(yè)務(wù)拓張會成為阻礙。

3.一旦設(shè)置了Common,就等于給地獄之門打開了一個小縫,每次業(yè)務(wù)迭代都會有一些不太好分類的東西放入Common,這就給維護Common的人帶來了非常大的工作量,而且這些工作量全都是體力活,非常容易出錯。

那么,不設(shè)Common會帶來哪些好處?

1.強迫工程師在業(yè)務(wù)拓張的時候?qū)⒁蕾嚬芾淼氖虑榭紤]進去,讓模塊在一開始發(fā)展的時候就有自己的土壤,成長空間和靈活度非常大。

2.減少各業(yè)務(wù)模塊或者Demo的體積,不需要的模塊不會由于Common的存在而包含在內(nèi)。

3.可維護性大大提高,模塊升級之后要做的同步工作非常輕松,解放了那個苦逼的Common維護者,更多的時間可以用在更實質(zhì)的開發(fā)工作上。

4.符合細粒度模塊劃分的架構(gòu)思想。

Common的好處只有一個,就是前期特別省事兒。然而它的壞處比好處要多太多。不設(shè)置Common,再小的模塊再小的代碼也單獨拎出來,最多就是Podfile里面要多寫幾行,多寫幾行最多只花費幾分鐘。但若要消除Common所帶來的罪孽,不是這幾分鐘就能搞定的事情。既然不用Common的好處這么多,那何樂而不為呢?

假設(shè)將來你的項目中有一個類是用來做Location的,哪怕只有兩個文件,也給他開一個模塊就叫Location。如果你的項目中有一個類是用來做ImageProcess的,那也開一個模塊就叫ImageProcess。不要都放到Common里面去,將來你再開新的項目或者新的業(yè)務(wù),用Location就寫依賴Location,用ImageProcess就寫依賴ImageProcess,不要再依賴Common了,這樣你的項目也好管理,管理Common的那個人日子過得也輕松(這個人其實都可以不需要了,把他的工資加到你頭上不是更好?:D),將來要升級,顧慮也少。

結(jié)束

一下子挖了個大坑,在開篇里扯了一些淡。

嗯,干貨會在后續(xù)的系列文章里面撲面而來的!

 

 

 

責任編輯:chenqingxiang 來源: casatwy
相關(guān)推薦

2011-03-14 15:52:50

Windows Azu

2011-06-21 09:14:01

Oracle查詢

2014-07-30 14:25:41

SwiftiBeacon

2017-04-10 13:43:34

AndroidGradleAS

2014-03-28 13:14:33

2022-08-01 08:18:58

網(wǎng)絡(luò)網(wǎng)絡(luò)協(xié)議

2015-07-20 16:37:11

2013-04-15 10:00:14

Hyper-V虛擬化網(wǎng)絡(luò)

2015-08-20 10:13:34

2023-01-06 18:50:55

架構(gòu)應(yīng)用

2021-07-05 22:11:38

MySQL體系架構(gòu)

2015-10-15 09:54:31

應(yīng)用架構(gòu)本地化iOS

2022-03-14 08:16:00

Java程序開發(fā)

2023-03-13 09:31:04

2021-03-12 09:21:31

MySQL數(shù)據(jù)庫邏輯架構(gòu)

2019-10-17 19:15:22

jQueryJavaScript前端

2023-06-21 10:33:13

SIGMOD阿里云數(shù)據(jù)庫

2025-06-23 09:08:00

2011-06-13 15:45:58

WEB標準SEO

2021-06-09 09:08:10

LDOlowdropoutr穩(wěn)壓器
點贊
收藏

51CTO技術(shù)棧公眾號

国产淫片av片久久久久久| 高潮按摩久久久久久av免费| 狠狠一区二区三区| 欧美激情综合五月色丁香| 欧美日韩国产第一页| 日韩欧美一区二区视频在线播放| 青青操视频在线播放| 懂色aⅴ精品一区二区三区| 成人一二三区视频| 萌白酱国产一区二区| www.cao超碰| yiren22综合网成人| 四虎5151久久欧美毛片| 亚洲一卡二卡三卡四卡五卡| 成人久久久久久| 女人黄色一级片| 日韩三区免费| 久久久久久久性| 欧美在线视频一区| 女人又爽又黄免费女仆| 欧美伦理91| 26uuu另类欧美亚洲曰本| 性亚洲最疯狂xxxx高清| 在线免费观看污视频| 国产美女精品写真福利视频| 成人动漫一区二区在线| 欧美精品videos另类日本| 国产大学生视频| 1024在线看片你懂得| 成人动漫一区二区在线| 成人精品一区二区三区| 久久精品视频2| 国产精品久久久久久久免费观看 | 国产91丝袜在线观看| 欧美成人免费观看| 少妇太紧太爽又黄又硬又爽小说| www.久久.com| 亚洲欧美日韩久久精品| 不卡视频一区二区三区| 日韩欧美高清在线观看| 女优一区二区三区| 91精品国产美女浴室洗澡无遮挡| 成人av在线播放观看| 亚州视频一区二区三区| 热久久国产精品| 欧美精品免费播放| 日韩在线观看视频一区二区| 卡一精品卡二卡三网站乱码| 欧美大肚乱孕交hd孕妇| 国产无套内射久久久国产| 在线毛片网站| 成人精品国产一区二区4080| 亚洲自拍小视频| 国产免费av一区| 天天影视天天精品| 久久久999精品| 免费a v网站| 亚洲欧美在线人成swag| 午夜精品福利在线| av电影一区二区三区| 三级黄视频在线观看| 紧缚捆绑精品一区二区| 高清亚洲成在人网站天堂| 极品尤物一区二区| 日韩欧美自拍| 日韩精品极品视频| 欧洲美女亚洲激情| 亚洲高清黄色| 亚洲成人午夜电影| 9999在线观看| 韩国中文字幕2020精品| 国产成人自拍网| 国产精品视频一| 特级西西444www大精品视频免费看| 日韩视频精品在线观看| 久久亚洲电影天堂| 精品一区二区三孕妇视频| 国产精品成人a在线观看| 久久天天躁狠狠躁老女人| 久久久国产成人| 999国产精品| 亚洲欧洲第一视频| 久久午夜夜伦鲁鲁片| 国产欧美一区| 亚洲精品视频免费| 久久人妻少妇嫩草av无码专区| 亚洲欧美成人vr| 亚洲精品久久久一区二区三区 | 久久网中文字幕| 久久精品亚洲| 26uuu久久噜噜噜噜| 欧美日韩黄色网| 久久精品不卡| 久久久噜久噜久久综合| 亚洲精品国产无码| 粉嫩av一区二区三区粉嫩| 欧美综合77777色婷婷| 完全免费av在线播放| 国产亚洲一区二区手机在线观看 | 免费在线视频你懂得| 国产99久久久国产精品潘金| 欧美极品一区二区| 四虎影视在线播放| 亚洲人成网站精品片在线观看| 久久国产亚洲精品无码| 欧美gv在线| 337p亚洲精品色噜噜狠狠| 一级片视频免费观看| 成人网ww555视频免费看| 精品卡一卡二卡三卡四在线| 亚洲成人福利视频| 日韩欧美一级| 欧美精品一区二区三区四区 | 国产九九在线视频| 欧美精选视频一区二区| 亚洲第一偷拍网| 中国一级特黄录像播放| 99久久www免费| 国产91在线播放九色快色| 国产免费一区二区三区四区五区| 亚洲一区图片| 日本视频久久久| 狠狠人妻久久久久久综合麻豆| 成人av高清在线| 亚洲美女自拍偷拍| 久久精品资源| 日韩欧美在线不卡| 一级黄色片日本| 欧美成人一品| 国外成人性视频| www.桃色av嫩草.com| 成人听书哪个软件好| 国产高清免费在线| 欧美亚洲黄色| 精品少妇一区二区三区| 欧美在线视频第一页| 麻豆国产欧美日韩综合精品二区| 亚洲va久久久噜噜噜久久天堂| a中文在线播放| 欧美性色黄大片手机版| 在线观看免费看片| 午夜精品久久久久久久白皮肤 | 成人黄色在线观看| 激情视频在线观看免费| 欧美日韩国产精品一区二区不卡中文| 亚洲日本无吗高清不卡| 免费观看在线黄色网| 亚洲精品成人精品456| 日本丰满少妇xxxx| 97人人做人人爽香蕉精品| 亚洲区在线播放| 亚洲图片在线视频| 国产在线精品一区二区夜色 | 韩国精品久久久999| www.久久综合| 亚洲成在人线免费| 在线观看国产三级| 久久九九国产| 性刺激综合网| 巨胸大乳www视频免费观看| 久久福利综合| 国产日产亚洲精品| 天天操天天爱天天干| 中文字幕成人在线观看| 农民人伦一区二区三区| 波多野结衣在线电影| 超碰cao国产精品一区二区| 日本韩国欧美超级黄在线观看| 日韩一区二区三区免费观看| 中文成人无字幕乱码精品区| 亚洲中字黄色| 无码免费一区二区三区免费播放| 欧美黄色网络| 欧美交受高潮1| 日本不卡免费播放| 欧美午夜不卡视频| 青娱乐在线视频免费观看| 日本中文字幕不卡| 天天干天天色天天爽| 51社区在线成人免费视频| 一道本无吗dⅴd在线播放一区| 国产一级片免费看| 国内精品在线播放| 青草视频在线观看视频| 伊人久久精品| 韩国日本不卡在线| 在线看的av网站| 欧美v日韩v国产v| www.国产一区二区| 亚洲人精品一区| 麻豆精品免费视频| 国产精品一区二区久激情瑜伽| 手机成人在线| 97精品在线播放| 国产老妇另类xxxxx| 久久99中文字幕| 天天做综合网| 蜜桃视频在线观看91| 国产区美女在线| 欧美电影影音先锋| www中文在线| 成人sese在线| 色国产在线视频| 波多野结衣在线网站| 你懂的视频一区二区| 国产一区再线| 18aaaa精品欧美大片h| 自拍亚洲一区欧美另类| 最近中文字幕免费在线观看| 久久亚洲综合色| 99色精品视频| 午夜日韩激情| 国产三级中文字幕| 日韩av大片| 欧美久久电影| 粉嫩一区二区三区四区公司1| 国产男女猛烈无遮挡91| 成人黄视频在线观看| 欧美一区欧美二区| 波多野结衣在线电影| 精品国产乱码久久久久久婷婷| 日本aaa视频| 大白屁股一区二区视频| 91欧美一区二区三区| 裸体在线国模精品偷拍| 无码少妇一区二区三区芒果| 精品一区二区三区的国产在线观看| 国产精品福利在线观看| 91av资源在线| 国产一区二区三区视频| 国产精品久久影视| 亚洲国产综合91精品麻豆| 顶级黑人搡bbw搡bbbb搡| 中文一区一区三区高中清不卡| 人妻av无码一区二区三区| 美女国产一区二区三区| 无码少妇一区二区三区芒果| 久久三级视频| 亚洲在线观看一区| 日本道不卡免费一区| 999热视频| 伊人久久av| 久久久999精品免费| 日本中文字幕视频在线| 精品国产乱码久久久久久影片| 国产婷婷一区二区三区久久| 精品久久香蕉国产线看观看亚洲| 精品少妇theporn| 亚洲福利一区二区| 日韩精品视频免费播放| 国产欧美日韩精品在线| 级毛片内射视频| 中文字幕欧美日本乱码一线二线| 亚洲天堂岛国片| 成人黄色一级视频| 少妇被狂c下部羞羞漫画| 成人国产精品免费观看| 亚洲第一页av| 国产精品丝袜在线| 国产97免费视频| 亚洲国产成人av好男人在线观看| 国产手机在线视频| 色综合久久久久久久久久久| 久久人妻无码aⅴ毛片a片app| 亚洲素人一区二区| 欧美精品一区二区蜜桃| 成人18在线| 亚洲国产精品激情在线观看| 精品国产乱码久久久久久图片 | 美女精品在线观看| 精品久久久久久久无码| 精品一区二区三区在线观看| 国产免费xxx| 国产精品草草| 亚洲激情啪啪| 欧美综合精品| 日韩欧美一区二区三区四区五区| 久久影院一区| 免费不卡av在线| 日本网站在线观看一区二区三区| 999这里有精品| 成人av综合在线| 老头老太做爰xxx视频| 亚洲精品少妇30p| 林心如三级全黄裸体| 亚洲摸摸操操av| 久久一区二区三区视频| 亚洲大片在线观看| 男人的天堂av网站| 日韩午夜三级在线| 亚洲日本中文字幕在线| 久久精品小视频| 特黄毛片在线观看| 久久久亚洲国产天美传媒修理工| 在线观看网站免费入口在线观看国内 | 国产欧美一区二区三区在线观看视频| 亚洲特黄一级片| 无码人妻丰满熟妇精品| 日韩一区二区三区电影 | 久久婷婷成人综合色| 永久av免费网站| 色婷婷av一区二区三区gif| 男人天堂中文字幕| 欧美三级中文字幕在线观看| 波多野结衣激情视频| 日韩一区二区视频在线观看| 欧美成熟毛茸茸| 欧美激情一级二级| 青青青国产精品| 欧美性xxxx69| 一区二区日韩免费看| 欧美熟妇另类久久久久久多毛| 久久久99免费| 日本va欧美va国产激情| 日韩一区二区三| 成人性爱视频在线观看| 欧美亚洲另类在线| 精品亚洲免a| 日韩黄色片在线| 亚洲毛片在线| 精品国产成人av在线免| 成人永久免费视频| 欧美丰满艳妇bbwbbw| 欧美裸体一区二区三区| 国产高清一级毛片在线不卡| 在线观看欧美日韩国产| 免费看男女www网站入口在线 | 国产一区二区精品久| 尤物av无码色av无码| 不卡的av中国片| 一级aaa毛片| 亚洲成人亚洲激情| 电影k8一区二区三区久久| 成人精品一二区| 欧美高清一级片| 国产一区再线| 亚洲精品裸体| 国产精品嫩草av| 午夜精品久久久久久久蜜桃app| 亚洲免费黄色片| 性日韩欧美在线视频| 97人人澡人人爽91综合色| 国产性生活免费视频| 国产成人av电影| 拔插拔插海外华人免费| 日韩欧美小视频| 性亚洲最疯狂xxxx高清| 人体久久天天| aaa毛片在线观看| 欧美激情一区二区三区在线| 中文字幕一区二区三区人妻四季 | 99久久亚洲精品日本无码| 精品国产3级a| 91探花在线观看| 蜜桃视频在线观看91| 日韩成人一区二区三区在线观看| www.偷拍.com| 国产日韩v精品一区二区| 丝袜美腿小色网| 日韩欧美一级二级| bl视频在线免费观看| 久久精品magnetxturnbtih| 久久久久久久久99精品大| 大肉大捧一进一出好爽视频| 韩日精品视频一区| 久久久久久天堂| 亚洲免费视频观看| 1234区中文字幕在线观看| 麻豆av一区| 久久电影网站中文字幕| 欧洲猛交xxxx乱大交3| 亚洲精品国产品国语在线| 成人mm视频在线观看| 天堂а√在线中文在线| 91免费精品国自产拍在线不卡| 欧美日韩一级大片| 亚洲女人天堂成人av在线| 日本免费在线一区| 久久久久久人妻一区二区三区| 久久久国产精华| 国产后入清纯学生妹| 2019精品视频| 国产精品一区二区中文字幕 | 巨茎人妖videos另类| 免费观看黄色的网站| 99久久久精品免费观看国产蜜| 日韩福利小视频| 日韩精品在线免费| 99精品视频在线免费播放 | 黄色综合网址| 粉嫩av一区二区三区天美传媒 | 校园春色综合网| 成人在线观看小视频| 亚洲欧美色婷婷| 白白在线精品| 成年网站免费在线观看| 色综合天天综合网天天看片| 在线观看三级视频| 97超碰人人看人人| 日日夜夜精品视频天天综合网|