Jack Jiang

          我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
          posts - 506, comments - 13, trackbacks - 0, articles - 1

          本文由騰訊技術(shù)yeconglu分享,原題“企業(yè)微信大型Android系統(tǒng)重構(gòu)之路”,下文進行了排版和內(nèi)容優(yōu)化等。

          1、引言

          企業(yè)微信本地部署版(下文簡稱為本地版)是從2017年起,脫胎于企業(yè)微信的一款產(chǎn)品。本地版的后臺服務能獨立部署在政府或者大型企業(yè)的本地服務器上。在一個已經(jīng)迭代了7年的大型Android端工程中,企業(yè)微信本地版不可避免地會暴露出一些遺留系統(tǒng)的特點。

          本文將探討我們在大型IM工程實踐中采用的一些行之有效的重構(gòu)方法和實例,以及如何讓一個大型軟件系統(tǒng)持續(xù)保持活力。

           
           

          技術(shù)交流:

          - 移動端IM開發(fā)入門文章:《新手入門一篇就夠:從零開發(fā)移動端IM

          - 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK備用地址點此

          (本文已同步發(fā)布于:http://www.52im.net/thread-4633-1-1.html

          2、企業(yè)微信技術(shù)合集

          企業(yè)微信的IM架構(gòu)設計揭秘:消息模型、萬人群、已讀回執(zhí)、消息撤回等

          企業(yè)微信針對百萬級組織架構(gòu)的客戶端性能優(yōu)化實踐

          揭秘企業(yè)微信是如何支持超大規(guī)模IM組織架構(gòu)的——技術(shù)解讀四維關系鏈

          企業(yè)微信客戶端中組織架構(gòu)數(shù)據(jù)的同步更新方案優(yōu)化實戰(zhàn)

          大型IM工程重構(gòu)實踐:企業(yè)微信Android端的代碼重構(gòu)之路》(* 本文)

          3、遺留系統(tǒng)的特點

          Martin Fowler 曾經(jīng)說過這樣一句話:

          Let’s face it, all we are doing is writing tomorrow’s legacy software today.

          你現(xiàn)在所寫的每一行代碼,都是未來的遺留系統(tǒng)。

          很多人以為存在時間很長的就是遺留系統(tǒng),但這其實是個誤區(qū)。時間長短并不能作為衡量遺留系統(tǒng)的標準。

          判斷遺留系統(tǒng)的幾個維度是:

          • 1)代碼;
          • 2)架構(gòu);
          • 3)測試;
          • 4)DevOps;
          • 5)技術(shù)和工具。

          遺留系統(tǒng)的真正特點其實是:

          • 1)代碼質(zhì)量差;
          • 2)架構(gòu)混亂;
          • 3)沒有測試;
          • 4)純手工的 DevOps(或運維);
          • 5)老舊的技術(shù)和工具。

          看看下面這 6 個問題是否在你的項目中也曾經(jīng)遇到過:

          如果你的產(chǎn)品也有類似的一些問題,符合的“癥狀”越多,你的產(chǎn)品就越趨近于一個遺留系統(tǒng)。當遺留系統(tǒng)這個泥球越滾越大時,我們對它投入的改造成本就會越來越高。

          遺留系統(tǒng)就像一輛老破舊的小汽車,不知道啥時候會出問題,維修成本也越來越高,想快也快不起來。

          4、什么是重構(gòu)

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

          具體來說:

          1)小型重構(gòu):是指對單個類內(nèi)部的重構(gòu)優(yōu)化。通常包括對方法名稱、方法參數(shù)數(shù)量、方法大小等內(nèi)容的修改。

          2)中型重構(gòu):是對多個類間的重構(gòu)優(yōu)化,通常的一些修改包括提取接口、超類、委托等調(diào)整。

          3)大型重構(gòu):是對整個系統(tǒng)的架構(gòu)進行重構(gòu)優(yōu)化,比如組件化、應用中臺架構(gòu)升級等,通常在做大型重構(gòu)時也會伴隨中小型的代碼重構(gòu)。

          以組件化為例:通過提取公用的基礎組件和業(yè)務組件,來提高代碼的可復用性,同時讓業(yè)務能獨立演進,就是一種大型重構(gòu)。重構(gòu)的目的是在不改變軟件可觀察行為的前提下,重點提高其可理解性,降低其修改成本。

          因此計算重構(gòu)收益的方式很簡單,從商業(yè)的角度來看,收益 = 軟件價值 - (研發(fā) + 維護成本)。

          如果我們只注重業(yè)務上的價值而忽略了軟件的研發(fā)維護成本,那么長此以往就會來到拐點 1。當研發(fā)維護成本超出業(yè)務價值,收益就開始負增長了。很多企業(yè)往往也是到這個拐點才意識到重構(gòu)的重要性。

          通常來說:重構(gòu)需要一段時間的投入,來慢慢降低研發(fā)維護成本,有的需要幾個月,有的甚至超過一年。但如果能堅持下來,就會來到拐點 3,此時收益開始正向增長。

          5、遺留系統(tǒng)重構(gòu)策略1:絞殺者模式

          5.1定義

          這個模式是指我們在替換一個軟件系統(tǒng)時,在舊系統(tǒng)旁邊搭建一個新系統(tǒng),讓它緩慢增長,與舊系統(tǒng)同時存在,逐步地“絞殺”舊系統(tǒng)。這個“逐步”的意思,其實就是增量演進。“同時存在”指的是并行運行。

          它有三個優(yōu)勢:

          • 1)第一:不會遺漏原有需求;
          • 2)第二:可以穩(wěn)定地提供價值,頻繁地交付版本,更好地監(jiān)控其改造進展;
          • 3)第三:避免“閉門造車”。

          劣勢主要來自迭代的風險和成本,絞殺的時間跨度會很大,存在一定風險,而且還會產(chǎn)生一定的迭代成本。

          5.2案例:啟動任務重構(gòu)

          5.2.1)問題:

          最開始時,我們的啟動任務邏輯全部都寫在 Application的 onCreate中。隨著啟動邏輯越來越復雜,這部分代碼越來越難以維護,而且很難監(jiān)控每個版本中由于啟動任務邏輯的變化,而帶來的啟動速度變化。

          下圖所示是一部分重構(gòu)前的啟動任務邏輯,各種業(yè)務的啟動任務都寫在 initMainProcess()中。

          5.2.2)方案:

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

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

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

          5.2.3)效果:

           

          重構(gòu)后,啟動Task的功能職責單一化,達到了高內(nèi)聚、低耦合的目標。而且對于新增的啟動任務,以及每個任務的速度劣化,都更方便監(jiān)控了。

          6、遺留系統(tǒng)重構(gòu)策略2:修繕者模式

          6.1定義

          絞殺植物模式適合用于新的系統(tǒng)和服務,替換舊的系統(tǒng)或舊系統(tǒng)中的一個模塊。在舊系統(tǒng)內(nèi)部,也可以使用類似的思想來替換一個模塊,只不過這個模塊仍然位于舊系統(tǒng)中,而不是外部。我們把這種方式叫做修繕者模式。

          修繕者模式是對于現(xiàn)有系統(tǒng)新增一層進行封裝,然后在保證新層對外提供功能不變的情況下,對系統(tǒng)內(nèi)部進行改造。

          6.2案例:云服務重構(gòu)——中間分發(fā)層重構(gòu)

          6.2.1)問題:

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

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

          Android開發(fā)中使用maven依賴其他模塊時,有implementation和api兩種方式。

          它們的區(qū)別是:

          • 1)implementation關鍵字用于將依賴的庫隱藏在當前模塊內(nèi),只能在當前模塊中訪問,不會傳遞給其他依賴該模塊的模塊;
          • 2)api關鍵字用于將依賴的庫的公共接口暴露給其他模塊,可以在其他依賴該模塊的模塊中直接訪問。

          但是由于分發(fā)層的隔離不夠嚴格,使用了api依賴云服務模塊,導致業(yè)務層也可以繞過分發(fā)層,直接調(diào)用本地版服務或者云服務。業(yè)務層開發(fā)需要根據(jù)具體情況,考慮應該在什么情況調(diào)用哪個服務,增加了維護成本和出錯的概率。

          6.2.2)方案:

          我們針對分層不夠清晰的問題,重構(gòu)了一套嚴格編譯隔離的云服務底層:業(yè)務層調(diào)用者必須通過中間分發(fā)層調(diào)用本地版服務或者云服務,無法繞過中間層。

          具體的做法是改成使用maven的implementation依賴方式,使得云服務底層的maven依賴不會傳遞給業(yè)務模塊,保證只有中間層能夠調(diào)用云服務底層,而業(yè)務層只能依賴中間層。

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

          6.2.3)效果:

          在保證新的中間層對外提供功能不變的情況下,我們漸進式地對中間層進行了重構(gòu),逐個模塊地把非預期中的跨層依賴都剝離掉。

          整個過程修改的Java文件數(shù)量超過800+,從此業(yè)務層只能通過中間層調(diào)用本地版通用底層或者Saas通用底層,跨層調(diào)用都會直接報編譯錯誤。

          7、遺留系統(tǒng)重構(gòu)策略3:拆遷者模式

          7.1定義

          基于原有的業(yè)務,新寫一套系統(tǒng),然后一次性將舊系統(tǒng)的數(shù)據(jù)和功能,遷移到新系統(tǒng)上。

          7.2案例:生命周期重構(gòu)

          7.2.1)問題:

          我們本地版原來已經(jīng)有一套頁面生命周期的監(jiān)控模塊,后來又引入了一套Saas的頁面生命周期監(jiān)控模塊。

          兩個模塊的功能大部分重復又不完全相同,維護的成本很大,比如開發(fā)做一個功能可能得同時修改兩個模塊的代碼,而且兩個模塊的修改都是類似的。

          7.2.2)方案和效果:

          雖然這個模塊的改動影響很大,但是為了徹底解決遺留代碼帶來的問題,我們在一次迭代中合并了兩個模塊的代碼,一次性切到新的唯一一個生命周期監(jiān)控模塊中。

          8、架構(gòu)級重構(gòu)實踐1:組件化

          8.1概述

          在本節(jié)中,我會介紹兩個架構(gòu)重構(gòu)的案例:組件化和云服務ProtoBuf定義統(tǒng)一。

          一般來說,挑戰(zhàn)可以歸納成兩大類:

          • 1)首先:是普遍性挑戰(zhàn),比如組件化重構(gòu),我將會展示我們是如何深入理解業(yè)務需求,找到量身定制的組件化重構(gòu)方案。
          • 2)其次:是特有的業(yè)務挑戰(zhàn)。以本地版為例,我們面臨的是歷史遺留問題,比如本地版和Saas兩種沖突的PB定義共存的情況。

          這種獨特的挑戰(zhàn)要求我們不僅要有技術(shù)上的廣度,還需要深度和創(chuàng)造性地思考。接下來,我將分享我們?nèi)绾伟踩〔降貙嵤┘軜?gòu)重構(gòu),同時保持系統(tǒng)持續(xù)迭代。

          8.2意義

          單體架構(gòu)是常見的架構(gòu)模式之一。

          通常所有開發(fā)人員基于單個模塊進行開發(fā),所有業(yè)務功能都集成在一起打包發(fā)布。單體架構(gòu)非常適合團隊規(guī)模小、業(yè)務復雜度低的產(chǎn)品,在項目起始階段能快速迭代進行驗證。

          隨著業(yè)務的持續(xù)演進,代碼不斷地膨脹和腐壞,所以代碼內(nèi)部的耦合度很高。在這樣的基礎上修改代碼,非常容易牽一發(fā)而動全身:修改一個 Bug,又引起另外一個 Bug;開發(fā)一個功能,又引起另外一個功能的異常。

          8.3重構(gòu)過程

          8.3.1)方案:

          這里先簡單講述一下企業(yè)微信組件化的技術(shù)方案,但是不會涉及太多細節(jié)。

          組件間的通信方案使用接口,即每個模塊各自提供一批對外的api接口,其它模塊只能訪問到這些api,如下圖所示。

          工程結(jié)構(gòu)上使用Module這種官方的形式進行工程結(jié)構(gòu)拆分,各組件之間能只能訪問到對方的api,通過只依賴api而不依賴本體的形式來實現(xiàn)的代碼隔離。

          組件化方案確定后,解耦遺留代碼的過程是漫長而瑣碎的。這里我更想著重敘述下本地版是如何推進組件化項目的進度,以及提高組件化實施的效率的。

          8.3.2)進度管理:

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

          劃分出不同功能模塊的分界線后,我們把不同模塊的解耦任務分給對應負責的開發(fā)。

          然后我們做了一個網(wǎng)站自動監(jiān)控每個模塊的解耦進度:

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

          我們通過這種方式持續(xù)推進這個維持了一年多的組件化大型重構(gòu)項目,讓每個模塊的解耦進度和組件化程度都可以一目了然。

          8.3.3)自動化重構(gòu)腳本:

          組件化的過程中,最常見的操作就是把更為內(nèi)聚的一些類移動到同一個組件內(nèi),以及為隔離的組件提供對外的API接口。為了提高組件化的效率,我們開發(fā)了許多解耦代碼的腳本,用于抽取組件API、移動類、移動資源,大大提高了全組開發(fā)實施組件化的效率。

          自動化重構(gòu)腳本分析和移動基礎庫ui_foundation的執(zhí)行示例:

          8.4優(yōu)化后效果

          抽取基礎庫40+,類1700+:

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

          9、架構(gòu)級重構(gòu)實踐2:統(tǒng)一云服務ProtoBuf定義

          9.1問題:兩套相似又不相同的ProtoBuf定義共存

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

          雖然后面我們已經(jīng)意識到這個問題,對本地版需求新增加的ProtoBuf字段索引都增加了1000,以此避免沖突,但是歷史已經(jīng)放出去的版本也無法再修改。如果沒有一個兼容舊版本的方案,那沖突的字段只能一直保留著。

          在本地版的業(yè)務層中,本地版的ProtoBuf和Saas的ProtoBuf一起編譯,由于不能存在包名和類名都一樣的類,所以本地版的ProtoBuf包名都從wework修改成了weworklocal。因此業(yè)務開發(fā)需要關注當前使用的是哪套ProtoBuf,而選擇引入不同的包名,大大增加了代碼的理解成本和開發(fā)成本。

          9.2方案:統(tǒng)一ProtoBuf定義

          9.2.1)沖突類型:

          為了實現(xiàn)兩套通用底層的PB統(tǒng)一,最大的問題是如何兼容兩份PB的沖突字段。

          本地版PB和SaasPB的字段沖突類型,主要有4種:

          • 1)類型相同,但名字不同,實際業(yè)務含義不同;
          • 2)類型不同,名字不同;
          • 3)本地版獨有字段;
          • 4)enum值沖突。

          9.2.2)分層設計:

          為了解決PB字段沖突的問題,我們增加了一個沖突轉(zhuǎn)換層:

          如上圖所示:

          • 1)上層UI統(tǒng)一使用Saas的PB結(jié)構(gòu);
          • 2)在本地版通用底層和UI之間,增加一層轉(zhuǎn)換層,負責把沖突的PB字段重新賦值;
          • 3)本地版的底層繼續(xù)使用原有的本地版PB。

          9.2.3)自動化重構(gòu)腳本:

          針對重復性工作,我們使用腳本對比Proto,找出沖突字段并進行自動化處理,提高效率。

          流程如下:

          自動化重構(gòu)腳本方案收益如下:

          • 1)無需手動對齊Proto文件 Proto文件數(shù)量470+,以處理一個文件15分鐘計算,可節(jié)省工作量約5人日;
          • 2)自動生成轉(zhuǎn)換代碼 沖突字段110+,每個沖突需實現(xiàn)3個轉(zhuǎn)換函數(shù),總計可以少寫6000+行代碼;
          • 3)出現(xiàn)新沖突時,可以重復生成新的轉(zhuǎn)換代碼。

          9.3優(yōu)化后效果

          1)對組件化的收益:可以消除約50%云服務需求導致的接口差異;

          2)減少了開發(fā)的理解和維護成本:后續(xù)維護的開發(fā)都不需要過多關注當前是需要使用本地版還是Saas的協(xié)議。

          10、代碼重構(gòu)實踐1:過大類重構(gòu)

          將大型的單體遺留系統(tǒng)重構(gòu)為組件化架構(gòu)后,我們有了更加低耦合、高內(nèi)聚的組件。但是回到組件內(nèi)部,代碼質(zhì)量對開發(fā)也非常重要。

          我相信你在過去的代碼里一定會遇到一種典型的代碼壞味道,那就是“過大類”。在產(chǎn)品迭代的過程中,由于缺少規(guī)范和守護,單個類很容易急劇膨脹,有的甚至達到幾萬行的規(guī)模。

          過大的類會導致發(fā)散式的修改問題,只要需求有變化,這個類就得做相應修改。

          隨著業(yè)務需求和代碼規(guī)模的不斷膨脹,我們針對過大類的重構(gòu)策略就是分而治之。通過分層將不同維度的變化控制在獨立的邊界中,使之能夠獨立的演化,從而減少修改代碼時彼此之間產(chǎn)生的影響。

          11、代碼重構(gòu)實踐2:會話列表重構(gòu)

          11.1業(yè)務分析和代碼分析

          對于遺留系統(tǒng)來說,比較常見的問題就是需求的上下文中容易存在斷層,所以第一步就是盡可能地了解、分析原有的業(yè)務需求。

          只有更清楚地挖掘原有的需求設計,才不會因為理解上的差異出現(xiàn)錯誤的代碼調(diào)整。接下來我們以會話列表頁面為例,講述我們重構(gòu)過大類的過程。

          下圖是我們對會話列表涉及的業(yè)務功能進行的梳理:

          下圖是會話列表頁面的示意圖:

          11.2架構(gòu)設計

          分析完之后,接下來就是進行架構(gòu)設計了。這一步讓我們在開始動手重構(gòu)前,想清楚重構(gòu)后的代碼將會是什么樣子,以終為始才能讓我們的目標更加清晰,讓過程更加可度量。

          現(xiàn)在主流APP框架都是用一套MVP或者MVVM框架來解耦。企微還是傳統(tǒng)的MVC方案,由于歷史原因修改成MVP或者MVVM都會有非常大的成本。

          于是我們創(chuàng)建了一個新的MVCs的框架。MVCs的主要理念是將View和Model的交互,變成一個可插拔的抽象的邏輯。所以一個Controller描述的是一組View與一組Model的關系,從理念上,它應與業(yè)務無關。MVCs架構(gòu)在面對企微這種復雜度的場景下,已經(jīng)可以較好得支撐實際面臨的業(yè)務需求。

          11.3小步安全重構(gòu)

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

          基于MVCs,我們將頁面重構(gòu)成了各個不同的Controller,把舊頁面超大類中的一個個業(yè)務逐步拆分到獨立的Controller中(如下圖所示)。

          每個controller對應一個具體的業(yè)務場景,例如:

          • 1)ConversationLogController對應日志相關的邏輯;
          • 2)ConversationDataInitController對應數(shù)據(jù)初始化;
          • 3)ConversationHeaderStatusBarViewInitController對應頭部狀態(tài)相關邏輯。

          11.4優(yōu)化后效果

          在采用MVCs框架進行重構(gòu)后,平均每個Controller的代碼行數(shù)降低到了約365行。這意味著我們成功地實現(xiàn)了Controller功能職責的單一化,達到了高內(nèi)聚、低耦合的目標。

          通過這些改進,我們的代碼變得更加清晰、易讀,降低了維護成本。同時,由于各個功能模塊之間的耦合度降低,我們可以更加靈活地對現(xiàn)有功能進行修改和擴展,以滿足不斷變化的業(yè)務需求。

          這些成果充分證明了MVCS框架在實際項目中的有效性和可行性,為后續(xù)重構(gòu)其他大型頁面提供了有益的借鑒。

          12、DevOps重構(gòu)實踐1:Bazel編譯

          企業(yè)微信本地版有大量的網(wǎng)絡通訊、數(shù)據(jù)庫存儲等底層通用能力是使用C++實現(xiàn)的,之前是以典型的Android.mk作為構(gòu)建工具來構(gòu)建動態(tài)庫。

          Bazel則是更為現(xiàn)代化的構(gòu)建工具:

          • 1)Bazel能夠緩存所有以前完成的工作,并跟蹤對文件內(nèi)容和構(gòu)建命令的更改,因此Bazel在構(gòu)建時只對需要重建的部分進行構(gòu)建;
          • 2)同時,Bazel支持項目以高度并行和增量的方式構(gòu)建,能夠進一步加快構(gòu)建速度。

          目前,本地版Android端的底層動態(tài)庫已經(jīng)全量換成使用Bazel構(gòu)建。

          下面是其中一個構(gòu)建腳本的例子:

          13、DevOps重構(gòu)實踐2:分支管理

          因為本地版需要面向很多大型政企用戶,不同的政企可能會有不同的包名、不同的發(fā)布分支、不同的發(fā)布計劃,而且這些發(fā)布計劃還會并行發(fā)布。

          為了讓各個角色的成員都能清晰了解和管理當前正在發(fā)布的分支和迭代,我們開發(fā)了專門的分支管理頁面,自動化拉取、合并不同的迭代分支,以及管理迭代的生命周期。

          14、DevOps重構(gòu)實踐3:流水線管理

          本地版客戶端的模塊眾多,不同的模塊可能是由不同的團隊負責開發(fā)的。

          下面是我們依賴的一些跨倉庫組件的示意圖:

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

          15、本文小結(jié)

          冰凍三尺非一日之寒 ,遺留系統(tǒng)不是一天就產(chǎn)生,也不單純因為一次提交就演化而來,而是隨著不斷的版本更迭、人員變換、代碼不斷累積腐化而導致的。

          遺留系統(tǒng)的技術(shù)債務就像一座冰山,雖然表面平平無奇,但是底下卻是縱橫交錯??膳碌氖呛芏鄷r候我們卻只看到了表面,而卻無法真正發(fā)現(xiàn)阻礙產(chǎn)品快速演進的元兇。

          主動、持續(xù)地改進甚至重構(gòu)系統(tǒng),才能適應變化。遺留系統(tǒng)重構(gòu)的最終目標是構(gòu)建一個具有可擴展性、高性能、高可用性的系統(tǒng)架構(gòu),提高系統(tǒng)的開發(fā)效率和產(chǎn)品的迭代速度。

          16、相關文章

          [1] 微信團隊原創(chuàng)分享:Android版微信的臃腫之困與模塊化實踐之路

          [2] 微信團隊原創(chuàng)分享:Android版微信從300KB到30MB的技術(shù)演進

          [3] Android版微信安裝包“減肥”實戰(zhàn)記錄

          [4] iOS版微信安裝包“減肥”實戰(zhàn)記錄

          [5] 移動端IM實踐:iOS版微信界面卡頓監(jiān)測方案

          [6] 微信團隊分享:極致優(yōu)化,iOS版微信編譯速度3倍提升的實踐總結(jié)

          [7] 微信團隊分享:微信支付代碼重構(gòu)帶來的移動端軟件架構(gòu)上的思考

          [8] 微信Windows端IM消息數(shù)據(jù)庫的優(yōu)化實踐:查詢慢、體積大、文件損壞等

          [9] IM跨平臺技術(shù)學習(九):全面解密新QQ桌面版的Electron內(nèi)存優(yōu)化實踐

          [10] 企業(yè)微信針對百萬級組織架構(gòu)的客戶端性能優(yōu)化實踐

          [11] 微信團隊分享:微信后端海量數(shù)據(jù)查詢從1000ms降到100ms的技術(shù)實踐

          [12] 阿里IM技術(shù)分享(七):閑魚IM的在線、離線聊天數(shù)據(jù)同步機制優(yōu)化實踐

          (本文已同步發(fā)布于:http://www.52im.net/thread-4633-1-1.html



          作者:Jack Jiang (點擊作者姓名進入Github)
          出處:http://www.52im.net/space-uid-1.html
          交流:歡迎加入即時通訊開發(fā)交流群 215891622
          討論:http://www.52im.net/
          Jack Jiang同時是【原創(chuàng)Java Swing外觀工程BeautyEye】【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
          本博文 歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明出處(也可前往 我的52im.net 找到我)。


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          Jack Jiang的 Mail: jb2011@163.com, 聯(lián)系QQ: 413980957, 微信: hellojackjiang
          主站蜘蛛池模板: 湛江市| 萝北县| 宿迁市| 贵溪市| 鹿邑县| 嘉义县| 临沧市| 司法| 兰溪市| 辽宁省| 平昌县| 财经| 肃北| 远安县| 明溪县| 东至县| 大悟县| 平潭县| 图片| 民乐县| 大足县| 晋江市| 怀仁县| 涿州市| 新龙县| 无锡市| 清涧县| 杨浦区| 台中市| 湛江市| 教育| 万年县| 青神县| 涿鹿县| 瑞安市| 鄱阳县| 宁远县| 宝兴县| 邻水| 盐边县| 桂平市|