欧美日韩午夜_五月天激情综合_国产精品久久久久一区二区三区_色女人av_国产福利av_欧美日韩中

企業(yè)微信大型Android系統(tǒng)重構(gòu)之路

2024-9-1 17:44| 發(fā)布者: 黃寧| 查看: 329| 評(píng)論: 0

作者:yeconglu
企業(yè)微信本地部署版(下文簡(jiǎn)稱為本地版)是從2017年起,脫胎于企業(yè)微信的一款產(chǎn)品。本地版的后臺(tái)服務(wù)能獨(dú)立部署在政府或者大型企業(yè)的本地服務(wù)器上。在一個(gè)已經(jīng)迭代了7年的大型Android系統(tǒng)中,企業(yè)微信本地版不可避免地會(huì)暴露出一些遺留系統(tǒng)的特點(diǎn)。本文將探討我們?cè)趯?shí)踐中采用的一些行之有效的重構(gòu)案例,以及如何讓一個(gè)大型軟件系統(tǒng)持續(xù)保持活力。

一、遺留系統(tǒng)的特點(diǎn)

Martin Fowler 曾經(jīng)說(shuō)過(guò)這樣一句話:
Let’s face it, all we are doing is writing tomorrow’s legacy software today.

你現(xiàn)在所寫的每一行代碼,都是未來(lái)的遺留系統(tǒng)。
很多人以為存在時(shí)間很長(zhǎng)的就是遺留系統(tǒng),但這其實(shí)是個(gè)誤區(qū)。時(shí)間長(zhǎng)短并不能作為衡量遺留系統(tǒng)的標(biāo)準(zhǔn)。判斷遺留系統(tǒng)的幾個(gè)維度是:代碼、架構(gòu)、測(cè)試、DevOps以及技術(shù)和工具。代碼質(zhì)量差、架構(gòu)混亂、沒(méi)有測(cè)試、純手工的 DevOps(或運(yùn)維)、老舊的技術(shù)和工具,才是遺留系統(tǒng)的真正特點(diǎn)。
看看下面這 6 個(gè)問(wèn)題是否在你的項(xiàng)目中也曾經(jīng)遇到過(guò)。



如果你的產(chǎn)品也有類似的一些問(wèn)題,符合的“癥狀”越多,你的產(chǎn)品就越趨近于一個(gè)遺留系統(tǒng)。當(dāng)遺留系統(tǒng)這個(gè)泥球越滾越大時(shí),我們對(duì)它投入的改造成本就會(huì)越來(lái)越高。遺留系統(tǒng)就像一輛老破舊的小汽車,不知道啥時(shí)候會(huì)出問(wèn)題,維修成本也越來(lái)越高,想快也快不起來(lái)。
二、重構(gòu)的類型和收益

重構(gòu)(名詞):對(duì)軟件內(nèi)部結(jié)構(gòu)的一種調(diào)整,目的是在不改變軟件可觀察行為的前提下,提高其可理解性,降低其修改成本。

小型重構(gòu)是指對(duì)單個(gè)類內(nèi)部的重構(gòu)優(yōu)化。通常包括對(duì)方法名稱、方法參數(shù)數(shù)量、方法大小等內(nèi)容的修改。中型重構(gòu)是對(duì)多個(gè)類間的重構(gòu)優(yōu)化,通常的一些修改包括提取接口、超類、委托等調(diào)整。大型重構(gòu)是對(duì)整個(gè)系統(tǒng)的架構(gòu)進(jìn)行重構(gòu)優(yōu)化,比如組件化、應(yīng)用中臺(tái)架構(gòu)升級(jí)等,通常在做大型重構(gòu)時(shí)也會(huì)伴隨中小型的代碼重構(gòu)。以組件化為例,通過(guò)提取公用的基礎(chǔ)組件和業(yè)務(wù)組件,來(lái)提高代碼的可復(fù)用性,同時(shí)讓業(yè)務(wù)能獨(dú)立演進(jìn),就是一種大型重構(gòu)。重構(gòu)的目的是在不改變軟件可觀察行為的前提下,重點(diǎn)提高其可理解性,降低其修改成本。因此計(jì)算重構(gòu)收益的方式很簡(jiǎn)單,從商業(yè)的角度來(lái)看,收益 = 軟件價(jià)值 - (研發(fā) + 維護(hù)成本)。



如果我們只注重業(yè)務(wù)上的價(jià)值而忽略了軟件的研發(fā)維護(hù)成本,那么長(zhǎng)此以往就會(huì)來(lái)到拐點(diǎn) 1。當(dāng)研發(fā)維護(hù)成本超出業(yè)務(wù)價(jià)值,收益就開(kāi)始負(fù)增長(zhǎng)了。很多企業(yè)往往也是到這個(gè)拐點(diǎn)才意識(shí)到重構(gòu)的重要性。
通常來(lái)說(shuō),重構(gòu)需要一段時(shí)間的投入,來(lái)慢慢降低研發(fā)維護(hù)成本,有的需要幾個(gè)月,有的甚至超過(guò)一年。但如果能堅(jiān)持下來(lái),就會(huì)來(lái)到拐點(diǎn) 3,此時(shí)收益開(kāi)始正向增長(zhǎng)。
三、遺留系統(tǒng)重構(gòu)策略

3.1 絞殺者模式

3.1.1 定義

這個(gè)模式是指我們?cè)谔鎿Q一個(gè)軟件系統(tǒng)時(shí),在舊系統(tǒng)旁邊搭建一個(gè)新系統(tǒng),讓它緩慢增長(zhǎng),與舊系統(tǒng)同時(shí)存在,逐步地“絞殺”舊系統(tǒng)。這個(gè)“逐步”的意思,其實(shí)就是增量演進(jìn)。“同時(shí)存在”指的是并行運(yùn)行。
它有三個(gè)優(yōu)勢(shì):第一,不會(huì)遺漏原有需求;第二,可以穩(wěn)定地提供價(jià)值,頻繁地交付版本,更好地監(jiān)控其改造進(jìn)展。第三,避免“閉門造車”。
劣勢(shì)主要來(lái)自迭代的風(fēng)險(xiǎn)和成本,絞殺的時(shí)間跨度會(huì)很大,存在一定風(fēng)險(xiǎn),而且還會(huì)產(chǎn)生一定的迭代成本。



3.1.2 案例:?jiǎn)?dòng)任務(wù)重構(gòu)

3.1.2.1 問(wèn)題

最開(kāi)始時(shí),我們的啟動(dòng)任務(wù)邏輯全部都寫在 ApplicationonCreate中。隨著啟動(dòng)邏輯越來(lái)越復(fù)雜,這部分代碼越來(lái)越難以維護(hù),而且很難監(jiān)控每個(gè)版本中由于啟動(dòng)任務(wù)邏輯的變化,而帶來(lái)的啟動(dòng)速度變化。
下圖所示是一部分重構(gòu)前的啟動(dòng)任務(wù)邏輯,各種業(yè)務(wù)的啟動(dòng)任務(wù)都寫在 initMainProcess()中。



3.1.2.2 方案

重構(gòu)后我們引入了啟動(dòng)任務(wù)管理框架,不同業(yè)務(wù)的啟動(dòng)任務(wù)劃分到不同的Task中,按照順序裝載到對(duì)應(yīng)的進(jìn)程。



每個(gè)Task實(shí)現(xiàn)一個(gè)相對(duì)比較內(nèi)聚的功能:



但是由于啟動(dòng)任務(wù)邏輯的復(fù)雜性,我們沒(méi)有一次性把所有啟動(dòng)邏輯都重構(gòu)成Task的形式,而是新邏輯使用Task的形式,舊邏輯逐步遷移。這種新舊寫法共存的情況維持了相當(dāng)長(zhǎng)的一段時(shí)間,直到所有啟動(dòng)邏輯都最終遷移到了新的啟動(dòng)框架中,后續(xù) ApplicationonCreate中也不允許再增加新的啟動(dòng)邏輯。
3.1.2.3 效果




重構(gòu)后,啟動(dòng)Task的功能職責(zé)單一化,達(dá)到了高內(nèi)聚、低耦合的目標(biāo)。而且對(duì)于新增的啟動(dòng)任務(wù),以及每個(gè)任務(wù)的速度劣化,都更方便監(jiān)控了。
3.2 修繕者模式

3.2.1 定義

絞殺植物模式適合用于新的系統(tǒng)和服務(wù),替換舊的系統(tǒng)或舊系統(tǒng)中的一個(gè)模塊。在舊系統(tǒng)內(nèi)部,也可以使用類似的思想來(lái)替換一個(gè)模塊,只不過(guò)這個(gè)模塊依舊位于舊系統(tǒng)中,而不是外部。我們把這種方式叫做修繕者模式。
修繕者模式是對(duì)于現(xiàn)有系統(tǒng)新增一層進(jìn)行封裝,然后在保證新層對(duì)外提供功能不變的情況下,對(duì)系統(tǒng)內(nèi)部進(jìn)行改造。



3.2.2 案例:云服務(wù)重構(gòu)--中間分發(fā)層重構(gòu)

3.2.2.1 問(wèn)題

本地版客戶端除了能連接到本地版的服務(wù)器,還能連接到Saas的云端服務(wù)器,實(shí)現(xiàn)這部分能力的模塊稱為云服務(wù)模塊。



為了在同一個(gè)UI頁(yè)面,同時(shí)支持使用本地版服務(wù)和云服務(wù),我們基于這兩個(gè)底層服務(wù)構(gòu)建了一個(gè)中間分發(fā)層。中間分發(fā)層能夠根據(jù)不同的情況,適當(dāng)?shù)貙⒄?qǐng)求分發(fā)給本地版服務(wù)或者云服務(wù)。



Android開(kāi)發(fā)中使用maven依賴其他模塊時(shí),有implementation和api兩種方式,它們的區(qū)別是:
    implementation關(guān)鍵字用于將依賴的庫(kù)隱藏在當(dāng)前模塊內(nèi),只能在當(dāng)前模塊中訪問(wèn),不會(huì)傳遞給其他依賴該模塊的模塊。api關(guān)鍵字用于將依賴的庫(kù)的公共接口暴露給其他模塊,可以在其他依賴該模塊的模塊中直接訪問(wèn)。
但是由于分發(fā)層的隔離不夠嚴(yán)格,使用了api依賴云服務(wù)模塊,導(dǎo)致業(yè)務(wù)層也可以繞過(guò)分發(fā)層,直接調(diào)用本地版服務(wù)或者云服務(wù)。業(yè)務(wù)層開(kāi)發(fā)需要根據(jù)具體情況,考慮應(yīng)該在什么情況調(diào)用哪個(gè)服務(wù),增加了維護(hù)成本和出錯(cuò)的概率。
3.2.2.2 方案

我們針對(duì)分層不夠清晰的問(wèn)題,重構(gòu)了一套嚴(yán)格編譯隔離的云服務(wù)底層:業(yè)務(wù)層調(diào)用者必須通過(guò)中間分發(fā)層調(diào)用本地版服務(wù)或者云服務(wù),無(wú)法繞過(guò)中間層。
具體的做法是改成使用maven的implementation依賴方式,使得云服務(wù)底層的maven依賴不會(huì)傳遞給業(yè)務(wù)模塊,保證只有中間層能夠調(diào)用云服務(wù)底層,而業(yè)務(wù)層只能依賴中間層。



重構(gòu)的過(guò)程是可以小步進(jìn)行的:先把一個(gè)業(yè)務(wù)模塊對(duì)云服務(wù)底層的依賴改成只依賴中間層,然后編譯,接著逐個(gè)處理編譯錯(cuò)誤。處理完一個(gè)業(yè)務(wù)模塊就可以提測(cè)這個(gè)模塊。
3.2.2.3 效果

在保證新的中間層對(duì)外提供功能不變的情況下,我們漸進(jìn)式地對(duì)中間層進(jìn)行了重構(gòu),逐個(gè)模塊地把非預(yù)期中的跨層依賴都剝離掉。
整個(gè)過(guò)程修改的Java文件數(shù)量超過(guò)800+,從此業(yè)務(wù)層只能通過(guò)中間層調(diào)用本地版通用底層或者Saas通用底層,跨層調(diào)用都會(huì)直接報(bào)編譯錯(cuò)誤
3.3 拆遷者模式

3.3.1 定義

基于原有的業(yè)務(wù),新寫一套系統(tǒng),然后一次性將舊系統(tǒng)的數(shù)據(jù)和功能,遷移到新系統(tǒng)上。
3.3.2 案例:生命周期重構(gòu)

3.3.2.1 問(wèn)題

我們本地版原來(lái)已經(jīng)有一套頁(yè)面生命周期的監(jiān)控模塊,后來(lái)又引入了一套Saas的頁(yè)面生命周期監(jiān)控模塊。兩個(gè)模塊的功能大部分重復(fù)又不完全相同,維護(hù)的成本很大,比如開(kāi)發(fā)做一個(gè)功能可能得同時(shí)修改兩個(gè)模塊的代碼,而且兩個(gè)模塊的修改都是類似的。
3.3.2.2 方案和效果

雖然這個(gè)模塊的改動(dòng)影響很大,但是為了徹底解決遺留代碼帶來(lái)的問(wèn)題,我們?cè)谝淮蔚泻喜⒘藘蓚€(gè)模塊的代碼,一次性切到新的唯一一個(gè)生命周期監(jiān)控模塊中。
四、架構(gòu)重構(gòu)

在本節(jié)中,我會(huì)介紹兩個(gè)架構(gòu)重構(gòu)的案例:組件化和云服務(wù)ProtoBuf定義統(tǒng)一。一般來(lái)說(shuō),挑戰(zhàn)可以歸納成兩大類。首先是普遍性挑戰(zhàn),比如組件化重構(gòu),我將會(huì)展示我們是如何深入理解業(yè)務(wù)需求,找到量身定制的組件化重構(gòu)方案。其次,是特有的業(yè)務(wù)挑戰(zhàn)。以本地版為例,我們面臨的是歷史遺留問(wèn)題,比如本地版和Saas兩種沖突的PB定義共存的情況。這種獨(dú)特的挑戰(zhàn)要求我們不僅要有技術(shù)上的廣度,還需要深度和創(chuàng)造性地思考。接下來(lái),我將分享我們?nèi)绾伟踩〔降貙?shí)施架構(gòu)重構(gòu),同時(shí)保持系統(tǒng)持續(xù)迭代。
4.1 組件化

4.1.1 意義

單體架構(gòu)是常見(jiàn)的架構(gòu)模式之一。通常所有開(kāi)發(fā)人員基于單個(gè)模塊進(jìn)行開(kāi)發(fā),所有業(yè)務(wù)功能都集成在一起打包發(fā)布。單體架構(gòu)非常適合團(tuán)隊(duì)規(guī)模小、業(yè)務(wù)復(fù)雜度低的產(chǎn)品,在項(xiàng)目起始階段能快速迭代進(jìn)行驗(yàn)證。
隨著業(yè)務(wù)的持續(xù)演進(jìn),代碼不斷地膨脹和腐壞,所以代碼內(nèi)部的耦合度很高。在這樣的基礎(chǔ)上修改代碼,非常容易牽一發(fā)而動(dòng)全身:修改一個(gè) Bug,又引起另外一個(gè) Bug;開(kāi)發(fā)一個(gè)功能,又引起另外一個(gè)功能的異常。
4.1.2 重構(gòu)過(guò)程

4.1.2.1 方案

這里先簡(jiǎn)單講述一下企業(yè)微信組件化的技術(shù)方案,但是不會(huì)涉及太多細(xì)節(jié)。
組件間的通信方案使用接口,即每個(gè)模塊各自提供一批對(duì)外的api接口,其它模塊只能訪問(wèn)到這些api,如圖:



工程結(jié)構(gòu)上使用Module這種官方的形式進(jìn)行工程結(jié)構(gòu)拆分,各組件之間能只能訪問(wèn)到對(duì)方的api,通過(guò)只依賴api而不依賴本體的形式來(lái)實(shí)現(xiàn)的代碼隔離。
組件化方案確定后,解耦遺留代碼的過(guò)程是漫長(zhǎng)而瑣碎的。這里我更想著重?cái)⑹鱿卤镜匕媸侨绾瓮七M(jìn)組件化項(xiàng)目的進(jìn)度,以及提高組件化實(shí)施的效率的。
4.1.2.2 進(jìn)度管理

一個(gè)完整的組件化重構(gòu)步驟如下圖所示:



劃分出不同功能模塊的分界線后,我們把不同模塊的解耦任務(wù)分給對(duì)應(yīng)負(fù)責(zé)的開(kāi)發(fā)。然后我們做了一個(gè)網(wǎng)站自動(dòng)監(jiān)控每個(gè)模塊的解耦進(jìn)度:



統(tǒng)計(jì)每日的解耦類和api數(shù)量:



我們通過(guò)這種方式持續(xù)推進(jìn)這個(gè)維持了一年多的組件化大型重構(gòu)項(xiàng)目,讓每個(gè)模塊的解耦進(jìn)度和組件化程度都可以一目了然。
4.1.2.3 自動(dòng)化重構(gòu)腳本

組件化的過(guò)程中,最常見(jiàn)的操作就是把更為內(nèi)聚的一些類移動(dòng)到同一個(gè)組件內(nèi),以及為隔離的組件提供對(duì)外的API接口。為了提高組件化的效率,我們開(kāi)發(fā)了許多解耦代碼的腳本,用于抽取組件API、移動(dòng)類、移動(dòng)資源,大大提高了全組開(kāi)發(fā)實(shí)施組件化的效率。
自動(dòng)化重構(gòu)腳本分析和移動(dòng)基礎(chǔ)庫(kù)ui_foundation的執(zhí)行示例:



4.1.3 效果

    抽取基礎(chǔ)庫(kù)40+,類1700+



    抽取業(yè)務(wù)模塊30+,抽取接口數(shù)2200+



4.2 云服務(wù)ProtoBuf定義統(tǒng)一

4.2.1 問(wèn)題:兩套相似又不相同的ProtoBuf定義共存

由于本地版的歷史需求和Saas既有相同也有不同的地方,所以造成了兩者的ProtoBuf有大量相同重合的地方,但是少量字段又并不是完全一樣的。而且在開(kāi)始沒(méi)有開(kāi)發(fā)規(guī)范的情況下,產(chǎn)生了沖突的數(shù)據(jù)字段,也就是在同一個(gè)Message結(jié)構(gòu)體的相同位置的字段,在本地版和Saas中的類型或者含義是不一樣的。



雖然后面我們已經(jīng)意識(shí)到這個(gè)問(wèn)題,對(duì)本地版需求新增加的ProtoBuf字段索引都增加了1000,以此避免沖突,但是歷史已經(jīng)放出去的版本也無(wú)法再修改。如果沒(méi)有一個(gè)兼容舊版本的方案,那沖突的字段只能一直保留著。
在本地版的業(yè)務(wù)層中,本地版的ProtoBuf和Saas的ProtoBuf一起編譯,由于不能存在包名和類名都一樣的類,所以本地版的ProtoBuf包名都從wework修改成了weworklocal。因此業(yè)務(wù)開(kāi)發(fā)需要關(guān)注當(dāng)前使用的是哪套ProtoBuf,而選擇引入不同的包名,大大增加了代碼的理解成本和開(kāi)發(fā)成本。
4.2.2 方案:統(tǒng)一ProtoBuf定義

4.2.2.1 沖突類型

為了實(shí)現(xiàn)兩套通用底層的PB統(tǒng)一,最大的問(wèn)題是如何兼容兩份PB的沖突字段。本地版PB和SaasPB的字段沖突類型,主要有4種:
    類型相同,但名字不同,實(shí)際業(yè)務(wù)含義不同類型不同,名字不同本地版獨(dú)有字段enum值沖突
4.2.2.2 分層設(shè)計(jì)

為了解決PB字段沖突的問(wèn)題,我們?cè)黾恿艘粋€(gè)沖突轉(zhuǎn)換層:



    上層UI統(tǒng)一使用Saas的PB結(jié)構(gòu)本地版通用底層和UI之間,增加一層轉(zhuǎn)換層,負(fù)責(zé)把沖突的PB字段重新賦值本地版的底層繼續(xù)使用原有的本地版PB
4.2.2.3 自動(dòng)化重構(gòu)腳本

針對(duì)重復(fù)性工作,我們使用腳本對(duì)比Proto,找出沖突字段并進(jìn)行自動(dòng)化處理,提高效率,流程如下:



自動(dòng)化重構(gòu)腳本方案收益如下:
    無(wú)需手動(dòng)對(duì)齊Proto文件 Proto文件數(shù)量470+,以處理一個(gè)文件15分鐘計(jì)算,可節(jié)省工作量約5人日。自動(dòng)生成轉(zhuǎn)換代碼 沖突字段110+,每個(gè)沖突需實(shí)現(xiàn)3個(gè)轉(zhuǎn)換函數(shù),總計(jì)可以少寫6000+行代碼。出現(xiàn)新沖突時(shí),可以重復(fù)生成新的轉(zhuǎn)換代碼。
4.2.3 效果

    對(duì)組件化的收益:可以消除約50%云服務(wù)需求導(dǎo)致的接口差異。減少了開(kāi)發(fā)的理解和維護(hù)成本:后續(xù)維護(hù)的開(kāi)發(fā)都不需要過(guò)多關(guān)注當(dāng)前是需要使用本地版還是Saas的協(xié)議。
五、代碼重構(gòu)

5.1 過(guò)大類重構(gòu)

將大型的單體遺留系統(tǒng)重構(gòu)為組件化架構(gòu)后,我們有了更加低耦合、高內(nèi)聚的組件。但是回到組件內(nèi)部,代碼質(zhì)量對(duì)開(kāi)發(fā)也非常重要。我相信你在過(guò)去的代碼里一定會(huì)遇到一種典型的代碼壞味道,那就是“過(guò)大類”。在產(chǎn)品迭代的過(guò)程中,由于缺少規(guī)范和守護(hù),單個(gè)類很容易急劇膨脹,有的甚至達(dá)到幾萬(wàn)行的規(guī)模。過(guò)大的類會(huì)導(dǎo)致發(fā)散式的修改問(wèn)題,只要需求有變化,這個(gè)類就得做相應(yīng)修改。
隨著業(yè)務(wù)需求和代碼規(guī)模的不斷膨脹,我們針對(duì)過(guò)大類的重構(gòu)策略就是分而治之。通過(guò)分層將不同維度的變化控制在獨(dú)立的邊界中,使之能夠獨(dú)立的演化,從而減少修改代碼時(shí)彼此之間產(chǎn)生的影響。
5.2 會(huì)話列表重構(gòu)

5.2.1 業(yè)務(wù)分析和代碼分析

對(duì)于遺留系統(tǒng)來(lái)說(shuō),比較常見(jiàn)的問(wèn)題就是需求的上下文中容易存在斷層,所以第一步就是盡可能地了解、分析原有的業(yè)務(wù)需求。只有更清楚地挖掘原有的需求設(shè)計(jì),才不會(huì)因?yàn)槔斫馍系牟町惓霈F(xiàn)錯(cuò)誤的代碼調(diào)整。接下來(lái)我們以會(huì)話列表頁(yè)面為例,講述我們重構(gòu)過(guò)大類的過(guò)程。下圖是我們對(duì)會(huì)話列表涉及的業(yè)務(wù)功能進(jìn)行的梳理:



下圖是會(huì)話列表頁(yè)面的示意圖:



5.2.2 架構(gòu)設(shè)計(jì)

分析完之后,接下來(lái)就是進(jìn)行架構(gòu)設(shè)計(jì)了。這一步讓我們?cè)陂_(kāi)始動(dòng)手重構(gòu)前,想清楚重構(gòu)后的代碼將會(huì)是什么樣子,以終為始才能讓我們的目標(biāo)更加清晰,讓過(guò)程更加可度量。
現(xiàn)在主流APP框架都是用一套MVP或者M(jìn)VVM框架來(lái)解耦。企微還是傳統(tǒng)的MVC方案,由于歷史原因修改成MVP或者M(jìn)VVM都會(huì)有非常大的成本。
于是我們創(chuàng)建了一個(gè)新的MVCs的框架。MVCs的主要理念是將View和Model的交互,變成一個(gè)可插拔的抽象的邏輯。所以一個(gè)Controller描述的是一組View與一組Model的關(guān)系,從理念上,它應(yīng)與業(yè)務(wù)無(wú)關(guān)。MVCs架構(gòu)在面對(duì)企微這種復(fù)雜度的場(chǎng)景下,已經(jīng)可以較好得支撐實(shí)際面臨的業(yè)務(wù)需求。
5.2.3 小步安全重構(gòu)

建立一個(gè)IController,抽象出和 Activity/Fragment相同的生命周期,然后在Activity/Fragment相同的生命周期執(zhí)行。同時(shí)一個(gè)IController可以包含多個(gè)IController,先執(zhí)行本身的邏輯,然后再執(zhí)行子IController邏輯,同時(shí)提供懶加載方案LazyController ,當(dāng)達(dá)到一定條件的時(shí)候才會(huì)加載,保證性能和效率。



基于MVCs,我們將頁(yè)面重構(gòu)成了各個(gè)不同的Controller,把舊頁(yè)面超大類中的一個(gè)個(gè)業(yè)務(wù)逐步拆分到獨(dú)立的Controller中:



每個(gè)controller對(duì)應(yīng)一個(gè)具體的業(yè)務(wù)場(chǎng)景,例如:
    ConversationLogController對(duì)應(yīng)日志相關(guān)的邏輯。ConversationDataInitController對(duì)應(yīng)數(shù)據(jù)初始化。ConversationHeaderStatusBarViewInitController對(duì)應(yīng)頭部狀態(tài)相關(guān)邏輯。
5.2.4 效果




在采用MVCs框架進(jìn)行重構(gòu)后,平均每個(gè)Controller的代碼行數(shù)降低到了約365行。這意味著我們成功地實(shí)現(xiàn)了Controller功能職責(zé)的單一化,達(dá)到了高內(nèi)聚、低耦合的目標(biāo)。
通過(guò)這些改進(jìn),我們的代碼變得更加清晰、易讀,降低了維護(hù)成本。同時(shí),由于各個(gè)功能模塊之間的耦合度降低,我們可以更加靈活地對(duì)現(xiàn)有功能進(jìn)行修改和擴(kuò)展,以滿足不斷變化的業(yè)務(wù)需求。這些成果充分證明了MVCS框架在實(shí)際項(xiàng)目中的有效性和可行性,為后續(xù)重構(gòu)其他大型頁(yè)面提供了有益的借鑒。
六、DevOps重構(gòu)

6.1 Bazel編譯

企業(yè)微信本地版有大量的網(wǎng)絡(luò)通訊、數(shù)據(jù)庫(kù)存儲(chǔ)等底層通用能力是使用C++實(shí)現(xiàn)的,之前是以典型的Android.mk作為構(gòu)建工具來(lái)構(gòu)建動(dòng)態(tài)庫(kù)。Bazel則是更為現(xiàn)代化的構(gòu)建工具:Bazel能夠緩存所有以前完成的工作,并跟蹤對(duì)文件內(nèi)容和構(gòu)建命令的更改,因此Bazel在構(gòu)建時(shí)只對(duì)需要重建的部分進(jìn)行構(gòu)建;同時(shí),Bazel支持項(xiàng)目以高度并行和增量的方式構(gòu)建,能夠進(jìn)一步加快構(gòu)建速度。
目前,本地版Android端的底層動(dòng)態(tài)庫(kù)已經(jīng)全量換成使用Bazel構(gòu)建,下面是其中一個(gè)構(gòu)建腳本的例子:



6.2 分支管理

因?yàn)楸镜匕嫘枰嫦蚝芏啻笮驼笥脩簦煌恼罂赡軙?huì)有不同的包名、不同的發(fā)布分支、不同的發(fā)布計(jì)劃,而且這些發(fā)布計(jì)劃還會(huì)并行發(fā)布。為了讓各個(gè)角色的成員都能清晰了解和管理當(dāng)前正在發(fā)布的分支和迭代,我們開(kāi)發(fā)了專門的分支管理頁(yè)面,自動(dòng)化拉取、合并不同的迭代分支,以及管理迭代的生命周期。



6.3 流水線管理

本地版客戶端的模塊眾多,不同的模塊可能是由不同的團(tuán)隊(duì)負(fù)責(zé)開(kāi)發(fā)的。下面是我們依賴的一些跨倉(cāng)庫(kù)組件的示意圖:



不同的組件由不同團(tuán)隊(duì)維護(hù)的流水線構(gòu)建,最后以maven的形式集成到本地版企業(yè)微信APP中。當(dāng)分支管理工具拉出一條新分支時(shí),就會(huì)自動(dòng)實(shí)例化各個(gè)業(yè)務(wù)組件的子流水線。這樣我們可以做到即使在多團(tuán)隊(duì)、多倉(cāng)庫(kù)、多分支開(kāi)發(fā)的情況下,組件編譯和集成編譯都可以全自動(dòng)進(jìn)行。



七、總結(jié)

冰凍三尺非一日之寒 ,遺留系統(tǒng)不是一天就產(chǎn)生,也不單純因?yàn)橐淮翁峤痪脱莼鴣?lái),而是隨著不斷的版本更迭、人員變換、代碼不斷累積腐化而導(dǎo)致的。
遺留系統(tǒng)的技術(shù)債務(wù)就像一座冰山,雖然表面平平無(wú)奇,但是底下卻是縱橫交錯(cuò)。可怕的是很多時(shí)候我們卻只看到了表面,而卻無(wú)法真正發(fā)現(xiàn)阻礙產(chǎn)品快速演進(jìn)的元兇。
主動(dòng)、持續(xù)地改進(jìn)甚至重構(gòu)系統(tǒng),才能適應(yīng)變化。遺留系統(tǒng)重構(gòu)的最終目標(biāo)是構(gòu)建一個(gè)具有可擴(kuò)展性、高性能、高可用性的系統(tǒng)架構(gòu),提高系統(tǒng)的開(kāi)發(fā)效率和產(chǎn)品的迭代速度。
分享到:

本版積分規(guī)則

交流熱線
17501437970 周一至周日:09:00 - 21:00

創(chuàng)贏網(wǎng)-致力于幫助普通人在創(chuàng)業(yè)之路上披荊斬棘、走向成功的專業(yè)網(wǎng)站,匯聚創(chuàng)新智慧與成功機(jī)遇的網(wǎng)絡(luò)天地,是創(chuàng)業(yè)者開(kāi)啟贏之征程的首選之地。

Powered by Discuz! X3.5 © 2023-2050 CHUANYING Team.

QQ|Archiver|手機(jī)版|小黑屋|創(chuàng)贏網(wǎng) ( 湘ICP備17022177號(hào)-3 )

GMT+8, 2025-5-22 16:55 , Processed in 0.521038 second(s), 30 queries .

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 秋霞毛片| 色噜噜色偷偷| 视频在线亚洲| www亚洲一区| 亚洲精品三级| av 一区二区三区| 亚洲国产区| 一本大道久久a久久精二百| 国产91打白嫩光屁屁网站| 日韩 综合| 亚洲午夜精品久久| 大香伊蕉在人线视频777| 国产在线免费| 黄色毛片一级| 午夜日韩福利| 国产一级二级在线| 日本x视频| 国产日韩欧美91| 不卡三区| 婷婷99狠狠躁天天躁中文字幕| 天天干天天草| 亚洲免费在线| 色伊人久久| 日韩美女一区| 久久国产精品-国产精品| 欧美在线三级| 99精品一区二区| 欧美日韩在线免费| 日韩一区二区三区av| 成人在线精品| 色女人av| runaway动漫免费观看完整| 亚洲精品在线播放| 欧美在线一区二区三区| 午夜天堂精品久久久久| 国产小毛片| 欧美视频在线免费| 一区二区免费视频| 中文字幕不卡在线| www.日韩欧美| 欧美在线二区|