[TOC]
盡管維基百科上對遺留系統的定義是:
> 一種舊的方法、舊的技術、舊的計算機系統或應用程序。
但是實際上,當你看到某個網站宣稱用新的框架來替換舊的框架的時候,你應該知曉他們原有的系統是遺留系統。人們已經不想在上面工作了,很多代碼也不知道是干什么的,也沒有人想去深究——畢竟不是自己的代碼。判斷是否是遺留代碼的條件很簡單,維護成本是否比開發成本高很多。
* 幾乎無法維護
* 代碼遺失
* 邏輯不清
* 沒有文檔或者不夠詳細、看不懂
* 關鍵點遺失
在維護這一類系統的過程中,我們可能會遇到一些原因來修改代碼。如《修改代碼的藝術》的一書中所說,修改軟件有四大原因:
* 增加特性
* 修復 Bug
* 改善設計
* 優化
當我們修改代碼之后,我們將繼續引進新的 Bug。
參考閱讀
-《修改代碼的藝術》
## 遺留代碼
我們生活息息相關的很多軟件里滿是錯誤、脆弱,并且難以擴展,這就是我們說的“遺留代碼”。
相信你也經常看到某某網站的高架構之路,會發現其中一個很有趣的過程就是他們會把之前的架構拋棄掉。接著,他們又做了一個這樣的系統,然后過些年這個系統又被重做了。究其原因,會發現這個架構是在幾年前設計的。在幾年前,他是非常好的架構。但是隨著時間的演變,他還是幾年前的架構。這是為什么呢?
### 遺留代碼
什么是遺留代碼?
> 沒有自動化測試的代碼就是遺留代碼,不管它是十年前寫的,還是昨天寫的。
從一個新手程序員到一個老鳥,我們的編程水平都在不斷增加。但是我們過去寫的代碼一直都在那里,但是我們一直都沒有足夠的勇氣去動他們。因為我們知道如果我們一不小心改錯了什么,就會導致一些意外的 Bug。這些 Bug 可能會對我們的編程生涯造成一些影響。
而我們不知道這樣做的后果,是因為我們沒有對原來的代碼進行測試。如果我們的代碼都是經過測試的,那么我們在修改中出的錯,都會在測試中加以體現。長此以往,沒有人敢去修改這些代碼。
既然他在舊的系統中工作得很好,那么我們就沒有理由去修改他們。當有新的需求出現時,我們就可以重新設計一個新的系統。
## 如何修改遺留代碼
> 即使是最訓練有素的開發團隊,也不能保證始終編寫出清晰高效的代碼。
然而,如果我們不去嘗試做一些改變,這些代碼就會遺留下去——成為遺留代碼,再次重構掉。即使說,重構系統是不可避免的一個過程,但是在這個過程中要是能抽象中領域特定的代碼、語言也是件不錯的事。
### 修改遺留代碼
So,如何開始修改代碼?如《修改代碼的藝術》一書所說,應該是下面的五個步驟:
1. 代碼修改點
2. 找到測試點
3. 打破依賴
4. 編寫測試
5. 修改并重構
在有測試的情況下重構現有的代碼才是安全的。而這些測試用例也是功能的體現,功能首先要得到保證了,然后才能保證一切都可以正常。不過,我更喜歡以下面三點概括他們:
* 守: 找到測試點。守,即保證原有的功能是正確的。在這基礎上,我們需要添加測試
* 破: 打破依賴。會導致遺留代碼的一個原因還有,原有代碼的耦合度比較高。因此,我們需要去打破這些耦合,重新構建依賴。
* 離: 修改并重構。
不過,我想你只要有前面的那些步驟。你為什么還需要看這一章的內容呢?
參考書籍:
* **《修改代碼的藝術》**
* **《持續交付指南:修改代碼的9條最佳實踐》**
## 網站重構
> 網站重構應包含結構、行為、表現三層次的分離以及優化,行內分工優化,以及以技術與數據、人文為主導的交互優化等。
從我所了解到的網站重構,它大概可以分為下面的幾類:
1. 速度優化
2. 功能加強
3. 模塊重構
下面就我們來看這三類的網站重構
### 速度優化
通常來說對于速度的優化也包含在重構中
* 壓縮 JS、CSS、image 等前端資源
* 程序的性能優化(如數據讀寫)
* 采用 CDN 來加速資源加載
* 對于 JS DOM 的優化
* HTTP 服務器的文件緩存
如對于壓縮前端資源這一類的重構,不僅僅需要從代碼層級來解決問題,也可以借由服務器緩存來解決問題。在這時候就需要去判斷應該由哪個層級來做這樣的事情——如果一件事可以簡單地由機器來解決,但是由人來解決需要花費大量的時間,這時就應該交由機器來解決。而如果由人來解決是一個長期受期,并且成本比較低的事,那么就應該由人來解決。如我們只需要在我們的構建腳本中引入 minify 庫就可以解決的事,那么應該交由人來做。
如,采用 CDN、HTTP 服務器的文件緩存這一類應該交由機器來做。
同時像程序性能優化、JS DOM 優化都應交由人來解決的事。特別是像程序性能優化,從長期來看可能是一件長期受益的事。當且僅當,我們遇到性能問題時,我們重構這部分代碼才可能帶來優勢。如果我們的網站的訪問量不是特別大,那么優化可能就是徒勞的。但是這種優化對于個人的成長還是挺有幫助的。
### 功能加強
一般來說功能加強,應該是由于需求的變動才引起對系統的重構需求:
* 解耦復雜的模塊 -> 微服務
* 對緩存進行優化
* 針對于內容創建或預留 API
* 需要添加新的 API
* 用新的語言、框架代替舊的框架(如 Scala, Node.js, React)
### 模塊重構
深層次的網站重構應該考慮的方面
* 減少代碼間的耦合
* 讓代碼保持彈性
* 嚴格按規范編寫代碼
* 設計可擴展的 API
* 代替舊有的框架、語言
* 增強用戶體驗