網際網路分層架構的本質,是資料的移動。
網際網路分層架構演進的核心原則:讓上游更高效的獲取與處理資料(複用),讓下游能遮蔽資料的獲取細節(封裝)。
不管資料怎麼移動,最終都會匯聚到客戶端。服務端的分層架構設計已經講了很多,客戶端的分層架構設計應該怎麼玩呢,服務端的分層架構設計是否有能夠借鑑的地方呢,今天和大家簡單聊一聊。
先來看小詩一首:
《Android猿》
曾經
所有程式碼
都被寫在Activity裡
幾乎
沒有程式碼
可以複用
每當
看到Activity裡
2000行的函式
我就
想要離職
上面,是團隊中一個文藝Android程式設計師的自述,表達的核心觀點是:幾乎所有程式碼都寫在了Activity裡(不理解Activity的,暫且認為是MVC裡的view層),完全沒有封裝和複用。
驗證使用者名稱密碼拉取好友列表拉取使用者資訊拉取好友資訊拉取離線訊息登入整個邏輯不能複用登入過程中的每個子邏輯也無法複用假設產品裡有一個“離線後重新登入”的功能,步驟與登入相同,就需要把上述在“重新登入Activity”裡程式碼複製一遍。
又假設產品裡有一個地方需要“拉取使用者資訊”,也將把“登入Activity”裡“拉取使用者資訊”的程式碼複製一遍。
封裝複用的道理誰都懂,拷貝程式碼的壞處也誰都明白,那為什麼大家還這麼做,讓程式碼越來越“腐爛”呢,根據個人經驗,主要是這麼幾點原因:
早期業務壓力大,APP是少數幾個同學的,沒有提前做規劃後期程式碼越來越臃腫,不敢動,一動怕影響功能,怕出問題,怕擔責任專案中,是以功能介面進行編碼劃分的,一個同學會同時負責MVC三部分編碼,加之專案壓力又大,既然是一個人寫,就沒必要分層了,搞多了呼叫反而麻煩專案中,有個需求好像之前做過,程式碼一看,寫在Activity裡,糾結。抽象成函式?還得改別人的程式碼,算了,還是拷貝一份吧…不管歷史原因,專案原因,個人的原因,大家都知道分層抽象,程式碼複用是正確的,那有什麼方案能夠將這個分層抽象落地,從後端的分層架構中是否有可借鑑的地方呢?
一個典型業務系統的後端架構如上:
web-server層呼叫RPC介面,從service層獲取資料,拼裝html/json,完成資料展現biz-service/data-service向上遊提供可複用的原子介面,實現業務邏輯,並層通過DAO層,從db層獲取資料db層提供資料APP端的分層架構不是非常相似麼?還是以登入業務為例:
登入Activity有兩個按鈕,一個確認按鈕,一個取消按鈕,這兩個按鈕的點選,分別只能呼叫一個函式:
on_LoginConfirm_Click
on_LoginCancel_Click
這裡相當於展現層,除了互動與展現,View層只能呼叫這兩個函式
這兩個函式的實現,是通過若干可複用的“原子業務邏輯”函式實現的驗證使用者名稱密碼: bool verifyPass(name, pass)
拉取好友列表: List<uid>getFriendList(uid)
拉取使用者資訊: Use rgetUserInfo(uid)
拉取好友資訊: List<User>getUserInfo(List<f_uid>)
拉取離線訊息: List<Msg>getOfflineMst(uid)
這相當於服務層,實現業務邏輯,提供封裝和複用
“原子業務邏輯”函式執行的過程中,需要訪問資料,資料的獲取又分為兩類:同步獲取:通過檔案,記憶體,本地資料庫獲取
非同步獲取:從server獲取,往往通過回撥實現
這裡相當於資料層,向上遊遮蔽資料獲取的複雜性,分別用不同的Proxy去實現
在這種結構下:
展現層非常輕,只調用一個函式,用於展現資料“原子業務邏輯”可以複用,不同的展現層Activity可以隨意組合,實現不同的業務邏輯,用於處理資料Proxy對上游遮蔽的資料獲取的複雜性,向上遊提供資料獲取介面,用於獲取資料網際網路分層的架構的本質,是資料的移動,分層架構封裝複用的思想,前後端有共通的地方。明明知道要封裝和複用,為何實現起來如此的困難呢?
Activity裡一坨坨複雜的程式碼,也是你曾經的痛麼?