架構(gòu)的選擇
在遇到需要實現(xiàn)一個完整的項目時,就不得不考慮該如何整理代碼結(jié)構(gòu),規(guī)劃模塊分層,模塊中間如何交互等等問題。在一開始的時間,我會嘗試套用各種各樣的架構(gòu),不過最近回眸的時候,發(fā)現(xiàn)這種做法是錯誤的。天下架構(gòu)千萬種,適合你的卻不多。
思考的起點,最好從變與不變這個角度來觸發(fā)。首先了解哪些是變的,從這一點開始思考,將重心放在變的部分上面,這樣的架構(gòu)才是合理的。
我舉一個例子,一個運營型很強的產(chǎn)品,經(jīng)常開展各種活動,活動樣式各不相同,邏輯復(fù)雜。變的地方,就在于靈活的活動上面。如果在客戶端上埋各種卡片樣式,不僅會使得客戶端代碼復(fù)雜,也無法滿足活動的動態(tài)能力。每當(dāng)上線一種新活動,就需要更新客戶端版本。反之,將變的地方放置在服務(wù)端,客戶端只做展示,不再需要知曉業(yè)務(wù)細節(jié),這樣就會好很多??蛻舳颂峁┗A(chǔ)的展示能力,登錄、下載等等基礎(chǔ)操作,服務(wù)端通過雙方協(xié)定好的協(xié)議下發(fā)對應(yīng)的指令,就能靈活地展示卡片。
Android Clean 架構(gòu)
通常我們開發(fā)的APP,變化最大的是業(yè)務(wù)需求。在這樣的產(chǎn)品上面,每個迭代都有可能有新功能的加入,老舊功能的修繕。
對于這種業(yè)務(wù)變化較為頻繁的應(yīng)用而言,就需要在客戶端本地做好基礎(chǔ)工作,架構(gòu)上要足夠通用,支持新業(yè)務(wù)加入。滿足這樣的架構(gòu)有很多,這里比較推薦[Clean 架構(gòu)](https://github.com/android10/Android-CleanArchitecture)。
關(guān)于 Clean 架構(gòu)的文章很多,我就不再這里具體展開了,大家有興趣的,可以看以下的鏈接。
一種更清晰的Android架構(gòu)
Architecting Android…The clean way?
在這里還是強調(diào)下,變化的是新的業(yè)務(wù)需求和老舊業(yè)務(wù)的調(diào)整,因而需要在這里提供擴展性十足,魯棒性高的架構(gòu)。
事件驅(qū)動架構(gòu)
并不是所有情況都能用上面的框架來實現(xiàn)。同樣我用例子來說明,我們做一個播放器。播放器的邏輯是非常復(fù)雜的,需要考慮很多方面的事情,例如播放狀態(tài)、用戶操作、網(wǎng)絡(luò)情況等等,如果我們正向思考,那這個代碼就很難寫了。
變的是播放的各種狀態(tài),用戶操作等,而我們要做的就是去相應(yīng)這些變化,而非正向地操作這些變化。這里的架構(gòu)最好采用事件驅(qū)動模型,在實現(xiàn)中維護一個狀態(tài)機,我們所需要做的事情是切換狀態(tài),并相應(yīng)狀態(tài)變化,這樣寫起來就會有條理很多。
例如播放的狀態(tài),有 Idle、Preparing、Playing、Paused、Stopped 等等,UI界面上響應(yīng)相應(yīng)的狀態(tài)并做出變化,例如播放按鈕在接受到 Paused -> Playing 的狀態(tài)變化后,將按鈕由播放變?yōu)?code>暫停。
One Model
這種模式一般適用于非常靈活的情形,例如我前面提及的第一個例子,在這種架構(gòu)下,客戶端作為展示平臺,并不參與業(yè)務(wù)邏輯。這種架構(gòu)有很多種實現(xiàn)方式,簡單的方式有 webview,高階一點的有各種 Web Native Framework。
但在這里介紹另一種方式,純粹的 Native 方式??蛻舳俗陨碜鳛橐粋€渲染平臺,指定自身可以支持的組件(Cards, Button, TextView etc.),和相應(yīng)支持的功能(Download, Jump to Web, Open File etc.)??蛻舳舜藭r與服務(wù)端定義好協(xié)議,當(dāng)服務(wù)器端根據(jù)協(xié)議下發(fā)指令時,客戶端需要解析它們,并展示相應(yīng)的組件,綁定上對應(yīng)的操作,這樣下來,客戶端就成了一定程度上的瀏覽器了。