完備路由系統(tǒng)

現(xiàn)在很多應(yīng)用都在內(nèi)部跳轉(zhuǎn)中使用了路由系統(tǒng),這種從web搬過(guò)來(lái)的東西混巧。但是功能卻并不完善姜挺,就像比較有名的JLRouter和MGJRouter盐类。這里就來(lái)聊聊更加完善的系統(tǒng)的幾個(gè)部分晰绎。

前言

現(xiàn)在很多的應(yīng)用都在一個(gè)非常大的量級(jí)了锭吨,已經(jīng)不可能由幾個(gè)人的小團(tuán)隊(duì)來(lái)開(kāi)發(fā)了,那么模塊化就非常必要了寒匙。相比很多人說(shuō)的組件化(Component),我覺(jué)得模塊化(Module)更為貼切一點(diǎn)。

說(shuō)到模塊化锄弱,那么模塊間的通信就非常重要了考蕾,如果僅僅是通過(guò)api來(lái)做通信,就不夠靈活会宪,而且可能會(huì)增加了集成成本肖卧。一旦涉及到接口變更就需要修改多個(gè)模塊。這樣路由系統(tǒng)便是頁(yè)面間跳轉(zhuǎn)的一個(gè)非常重要模塊掸鹅,可以說(shuō)他承載了整個(gè)最核心的部分塞帐。一個(gè)好的,完善的路由系統(tǒng)可以讓一個(gè)系統(tǒng)更加穩(wěn)定和開(kāi)發(fā)簡(jiǎn)單巍沙。而一個(gè)功能欠缺的路由系統(tǒng)則有可能將整個(gè)應(yīng)用帶入一個(gè)泥潭葵姥。

目前比較有名的幾個(gè)實(shí)現(xiàn),都非常簡(jiǎn)單句携,而且非常好用榔幸。但這是對(duì)一個(gè)整體的應(yīng)用來(lái)說(shuō)的,如果是一個(gè)多團(tuán)隊(duì)開(kāi)發(fā)的應(yīng)用矮嫉,就有部分缺陷了削咆。所以為了應(yīng)對(duì)這種缺陷,蘑菇街和京東都開(kāi)發(fā)了一個(gè)管理平臺(tái)蠢笋,來(lái)專門管理這些路由系統(tǒng)拨齐,解決這種缺陷。

這些路由實(shí)現(xiàn)在目前已經(jīng)基本滿足需求了昨寞,但是在未來(lái)可能會(huì)進(jìn)行的模塊拆分瞻惋,則需要功能更加強(qiáng)大的路由系統(tǒng)。所以我提出一種更加完備的路由系統(tǒng)编矾∈焓罚可能這里有過(guò)度設(shè)計(jì)的成分,但是作為未來(lái)的擴(kuò)展性窄俏,我覺(jué)得還是有必要的蹂匹。

完備路由

既然我們是從web那里抄過(guò)來(lái)的想法,那么為什么不抄的完整一些呢凹蜈?

回溯 history

目前的幾個(gè)路由系統(tǒng)都沒(méi)有提供這個(gè)功能限寞,而這個(gè)功能我覺(jué)的是非常非常重要的一個(gè)功能。當(dāng)我們需要判斷上個(gè)頁(yè)面是什么頁(yè)面的時(shí)候仰坦,只能通過(guò)判斷controller隊(duì)列中的類型履植!這完全違背了黑箱這種原則。

同時(shí)我們可能需要回退多個(gè)頁(yè)面或者回退到某個(gè)頁(yè)面的時(shí)候悄晃,沒(méi)有歷史記錄的支持玫霎,在合作開(kāi)發(fā)的時(shí)候絕對(duì)是個(gè)災(zāi)難凿滤。

history給我們的功能好處也是非常多的。除了上述幾個(gè)場(chǎng)景中特別需要以外庶近,對(duì)我們的debug以及分析也是非常有幫助的翁脆。甚至我們可以記錄和導(dǎo)出history來(lái)查看用戶的操作流程,雖然不能代表所有的動(dòng)作鼻种,但也可以展示用戶的一系列行為反番,或者在crash分析中自動(dòng)帶上該信息。

自定義進(jìn)入退出

我們的每個(gè)頁(yè)面都不是固定的push的叉钥,也可能是present的罢缸,所以相應(yīng)的返回也是不一樣的,然而目前幾個(gè)路由系統(tǒng)都只有進(jìn)入的方式投队,并沒(méi)有退出的方式枫疆。那么只能交給人來(lái)處理這種事情,當(dāng)某個(gè)模塊成為黑箱的時(shí)候蛾洛,外部又怎么去判斷呢养铸?

所以進(jìn)入(push)和回退(pop)操作都需要有對(duì)應(yīng)的行為,這就承接了上一個(gè)history的必要性了轧膘。這樣我們同樣是進(jìn)入(push)和回退(pop)钞螟,當(dāng)行為是present時(shí),就對(duì)應(yīng)為presentdismiss谎碍。

甚至在內(nèi)嵌的網(wǎng)頁(yè)中也可以接入native的路由系統(tǒng)鳞滨,那么這樣的pushpop就對(duì)應(yīng)了網(wǎng)頁(yè)的跳轉(zhuǎn)和返回了。同時(shí)這樣也屏蔽了模塊內(nèi)部的具體行為蟆淀,模塊修改展示方式也不會(huì)影響外部的處理邏輯拯啦。更好的形成一個(gè)黑盒模塊。

子路由

這個(gè)在web中是不存在的熔任,但是在native的app中我覺(jué)得有必要褒链。每個(gè)模塊,或者內(nèi)嵌的網(wǎng)頁(yè)都應(yīng)該是個(gè)子路由系統(tǒng)疑苔。

為什么需要子路由系統(tǒng)呢甫匹?這里舉一個(gè)例子:

Root --[push]-> VC
                |
            [present]
                \
                 --> VC2 --[push]-> VC3 -->...

當(dāng)我們需要去完成一個(gè)系列的完整動(dòng)作的時(shí)候,往往會(huì)present出一個(gè)新的navigation來(lái)處理這一系列動(dòng)作惦费,而這些行為在任意一個(gè)節(jié)點(diǎn)都可能會(huì)返回兵迅,同時(shí)又可能在任意的一個(gè)地方present出來(lái)。那么如果要滿足這種情景又需要人為的去處理很多邏輯薪贫,這就埋下了隱患恍箭。

如果我們把present出來(lái)的這一系列行為定義為子路由,那么如果需要返回時(shí)瞧省,只需要退出子路由中所有的history就可以了扯夭。

黑盒路由

如果項(xiàng)目變大以后鳍贾,可能就會(huì)存在上百個(gè)路由,那么這些路由中實(shí)際有效的(其他模塊可用交洗,或者公開(kāi)的)路由又有多少呢贾漏?我覺(jué)得應(yīng)該會(huì)很少吧,因?yàn)橥獠窟M(jìn)入一個(gè)其他模塊的入口基本是固定的藕筋,所以我們?yōu)槭裁葱枰┞哆@么多不必要的路由給外部呢。蘑菇街和京東為了管理這些路由干脆搞了一個(gè)管理系統(tǒng)梳码,來(lái)防止路由沖突隐圾。那么為什么我們不讓一個(gè)模塊內(nèi)的路由成為一個(gè)黑箱呢,只暴露外部需要的路由掰茶,而其他路由都經(jīng)過(guò)保護(hù)不能隨意訪問(wèn)暇藏。這樣也防止外部訪問(wèn)不該訪問(wèn)的功能。

這個(gè)功能是承接子路由的實(shí)現(xiàn)濒蒋,我們保持每個(gè)子路由內(nèi)部的黑盒盐碱,可以減少我們的錯(cuò)誤。

保持子路由的黑盒性的一個(gè)簡(jiǎn)單做法就是base url沪伙。依照restful來(lái)設(shè)計(jì)路由瓮顽,不同子路由系統(tǒng)給與一個(gè)base url,比如登錄模塊的路由可以增加base url /auth围橡。那么內(nèi)部和外部的行為可以概括為:

// 外部
push("/auth")
push("/auth/password")
// 內(nèi)部
push("~")
push("~/phone")
push("~/verify")
push("~/password")
// 退出整個(gè)模塊
pop("~")

重定向

有些頁(yè)面在某些條件下是不能進(jìn)入的暖混,這時(shí)候需要重定向去特定模塊來(lái)完成這個(gè)條件,完成后再次進(jìn)入該模塊翁授。所以我們需要重定向的功能拣播,否則就會(huì)增加很多依賴項(xiàng),導(dǎo)致不能真正的模塊分離收擦。

比如某個(gè)功能需要登錄模塊贮配,在我們沒(méi)有集成登錄模塊的時(shí)候就難以完成功能,而集成了登錄模塊又會(huì)導(dǎo)致模塊化僅僅只是個(gè)表面上的分離了塞赂,可能在真正開(kāi)發(fā)的時(shí)候還是把一大堆其他模塊給搞進(jìn)工程泪勒,那么這樣的模塊化有什么意義?如果擁有重定向就可以偽造一個(gè)重定向减途,讓他自動(dòng)放回需要的結(jié)果就可以了酣藻。這樣就可以排除其他模塊的干擾了和依賴了。

路徑依賴

這個(gè)其實(shí)時(shí)承接上個(gè)需求的鳍置,可以相當(dāng)于一個(gè)語(yǔ)法糖辽剧。

按照上個(gè)場(chǎng)景,我們?nèi)绾稳プ?cè)一個(gè)需要重定向的路由呢税产。那么我們可以引入一個(gè)路由依賴的功能怕轿,可以標(biāo)記每個(gè)路由的依賴選項(xiàng)偷崩。比如登錄的@requireLogin

這算是一個(gè)擴(kuò)展的功能吧撞羽。

中間件

目前主流的幾個(gè)路由還有一個(gè)非常欠缺的功能就是中間件阐斜。我們無(wú)法去從路由系統(tǒng)內(nèi)部知道我們經(jīng)過(guò)了哪些操作,是否需要過(guò)濾某些操作诀紊。

這個(gè)話題其實(shí)也關(guān)系著黑盒路由和重定向的問(wèn)題谒出。依照服務(wù)端的中間件設(shè)計(jì)方式,我們應(yīng)該需要為路由系統(tǒng)留出控制以及debug的入口邻奠。

擁有了中間件我們可以做什么笤喳?

  • debug,打印所有的入口和出口碌宴,完善我們的日志
  • 分模塊開(kāi)發(fā)的時(shí)候杀狡,可以mock其他有依賴的模塊
  • 監(jiān)視,是否調(diào)用了非法的接口或者使用了非法的參數(shù)

個(gè)人覺(jué)得中間件是一個(gè)系統(tǒng)所必須的功能贰镣,可以提供外部實(shí)現(xiàn)更多的功能和更靈活的控制呜象。

熱插件

這是一個(gè)額外的話題。由于我們的路由注冊(cè)基本上是在+load方法里面做的碑隆,所以當(dāng)我們的路由越來(lái)越多的時(shí)候恭陡,啟動(dòng)性能也會(huì)越來(lái)越差,那么提供熱插拔的功能是最好的干跛。同時(shí)熱插拔功能也相對(duì)應(yīng)的提高了路由的黑盒性子姜。

做成熱插件的形式還有一些好處。比如abtest的時(shí)候楼入,可以加載不同的插件來(lái)進(jìn)入不同的頁(yè)面哥捕。又或者在某個(gè)頁(yè)面出了線上問(wèn)題,需要降級(jí)為web來(lái)實(shí)現(xiàn)嘉熊,也可以通過(guò)替換插件來(lái)替換不同的頁(yè)面遥赚。

這是一個(gè)錦上添花的功能,所以我把他列到了最后阐肤。

總結(jié)

以上說(shuō)的幾個(gè)點(diǎn)可能給我們的編碼增加一些復(fù)雜度凫佛,而且還需要去理解這些概念才能很好的運(yùn)用。但這里的規(guī)劃完全是以模塊化為前提的孕惜,并且獨(dú)立為一個(gè)系統(tǒng)愧薛,不去依賴UIKit。所以從長(zhǎng)遠(yuǎn)來(lái)看這樣的實(shí)現(xiàn)是絕對(duì)有好處的衫画,如果有時(shí)間可以把這個(gè)想法實(shí)現(xiàn)出來(lái)毫炉。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市削罩,隨后出現(xiàn)的幾起案子瞄勾,更是在濱河造成了極大的恐慌费奸,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件进陡,死亡現(xiàn)場(chǎng)離奇詭異愿阐,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)趾疚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門缨历,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人糙麦,你說(shuō)我怎么就攤上這事戈二。” “怎么了喳资?”我有些...
    開(kāi)封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)腾供。 經(jīng)常有香客問(wèn)我仆邓,道長(zhǎng),這世上最難降的妖魔是什么伴鳖? 我笑而不...
    開(kāi)封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任节值,我火速辦了婚禮,結(jié)果婚禮上榜聂,老公的妹妹穿的比我還像新娘搞疗。我一直安慰自己,他們只是感情好须肆,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布匿乃。 她就那樣靜靜地躺著,像睡著了一般豌汇。 火紅的嫁衣襯著肌膚如雪幢炸。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天拒贱,我揣著相機(jī)與錄音宛徊,去河邊找鬼。 笑死逻澳,一個(gè)胖子當(dāng)著我的面吹牛闸天,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播斜做,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼苞氮,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了陨享?” 一聲冷哼從身側(cè)響起葱淳,我...
    開(kāi)封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤钝腺,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后赞厕,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體艳狐,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年皿桑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了毫目。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诲侮,死狀恐怖镀虐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情沟绪,我是刑警寧澤刮便,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站绽慈,受9級(jí)特大地震影響恨旱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜坝疼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一搜贤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧钝凶,春花似錦仪芒、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至哟沫,卻和暖如春铆隘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背南用。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工膀钠, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人裹虫。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓肿嘲,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親筑公。 傳聞我的和親對(duì)象是個(gè)殘疾皇子雳窟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器封救,智...
    卡卡羅2017閱讀 134,629評(píng)論 18 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,745評(píng)論 25 707
  • 路由是實(shí)現(xiàn)模塊間解耦的一個(gè)有效工具拇涤。如果要進(jìn)行組件化開(kāi)發(fā),路由是必不可少的一部分誉结。目前iOS上絕大部分的路由工具都...
    黑超熊貓zuik閱讀 3,919評(píng)論 8 52
  • 在讀書時(shí)期寫作文就是一件很頭痛的事惩坑,這次參加寫作訓(xùn)練營(yíng)也是想著逼自己一把掉盅,刻意練習(xí)提高一下慘不忍睹的文筆。不知...
    Emily80871閱讀 267評(píng)論 0 0
  • 同窗四載友誼重 激情共 志如松 激揚(yáng)文字 豪邁青春夢(mèng) 衛(wèi)水河畔風(fēng)雅頌 醉紅顔 赴豫東 牧野別后盼相逢 微信通 語(yǔ)氣...
    水天一色的美閱讀 550評(píng)論 64 93