iT邦幫忙

2021 iThome 鐵人賽

DAY 27
1
IT管理

邁向Tech Leader的成長之路系列 第 27

26. 如何淘汰萬年遺毒的code

前言

這篇文章適合給那些要處理Legacy System(舊系統)的朋友們看,如果你們團隊有系統的code是一團亂,而且完全沒人知道他為什麼可以動的話,你可以參考一下這篇演講給的建議。

演講總結

這篇文章討論的主題是我們要怎麼處理Legacy System。

那什麼是Legacy System呢?其實就是一個正在線上跑的舊服務,而且這個舊服務非常難維護,改進與擴展。而會這樣的原因,通常就是因為它overloaded了,承載了超過原本設計能負荷的事情。

一般來說Legacy System的產生原因是基於一系列的緊急事故(emergency),因為人力與時間不足,所以我們不斷的在原本的系統上加上應急方法(workaround),導致欠下一技術債(technical debt)。而有些狀況則是因為寫原本系統的人離開了,也沒好好交接好,想淘汰但又不太確定是誰在用。

無論成因為何,為了處理這種系統,我們可以想到三種方案:

方案一:繼續在上面加東西

這通常發生在沒時間或沒資源的情況下,基本上是下下策,畢竟你不知道什麼時候這個系統會完全扛不住爆炸。

方案二:完全重寫一個新的系統

很多時候這真的是蠻不錯的選擇,但想必他也有很多問題需要考慮:

  1. 沒時間重寫,或只來得及寫一半怎麼辦。
  2. Legacy System的複雜性總是被低估因為成功者謬誤(success bias)。
  3. Bug需要重新被發現與修正,前人踩過的雷往往會需要重踩一次。
  4. 新的feature會被delay。
  5. 資料遷移(data migration)過程總是非常痛苦。
  6. 還是需要同時維護新舊系統。

方案三:漸近式重寫(progressive rewrite)

Progressive rewrite又被稱為扼殺者模式(Strangler pattern)。意思就是在既有系統上慢慢抽換掉內部元件,直到整個系統都被重新寫過。

這個方式雖然很安全,但是不代表很直觀。而它通常花的開發時間會比整個重寫還要來的久,但是好處是,比起重寫後要完美取代舊系統所需要花的時間可能少了些。因為很可能會少了後面修修補補的部份。

要怎麼做到progressive rewrite呢?

要回答這個問題,講者想先討論:什麼是code quality?

當我們講到code quality,很多人會想到TDD、test coverage、design pattern這些東西,但這些其實並不是評斷code質量的依據。

真正判斷code quality的是,你有沒有辦法保持快速deliver feature或快速發現bug。如果你的code quality很高,意思就是對於新的feature你的開發時間並不會隨著codebase增加而巨幅增加,理解難易度、debug難度亦然。

因此保持好的code quality的重要關鍵是模組化(modularization),如果系統可以分割清楚每個元件的任務,便可以輕易抽換內部元件,或輕易增加新功能上去。

有了這個概念後,我們就可以來看應該要怎麼回春(rejuvenation)

  1. 先講低onboarding這個legacy system的複雜度,讓新使用者可以快速的上手與設置好工作環境。
  2. 寫好end to end test,確認外部系統與他溝通時的結果是可預期的。
  3. 將code想辦法切成小module。
  4. refactor系統讓他可以好拆開,與變成可抽換式的系統。
  5. 重寫一個一個module慢慢取代舊有系統
  6. 不要丟棄你的舊code,未來可供參考。

Source code rejuvenation is not refactoring

而要注意的是rejuvenation與重構(refactoring)是不同的。

Refactor是修正內部的實作方式,是一種technical的improvement,所以業務邏輯是不會被改到的。但是Rejuvenation是整套的翻修,是會牽扯到要重新設計product本身,所以通常rejuvenation是需要產品經理(PM)們的參與的。

個人心得

這篇演講對我來說沒有太多insight,不過自己倒是在處理legacy system是真的蠻有經驗的,畢竟我跟著公司從無法scale的monolithic,一路走到現在拆開來的microservice;加上組織內部一天到晚在reorg,各種handover takeover常常中間都會有資訊消失。所以處理legacy system基本上是每天在做的XD。

什麼時候要重寫整個系統?

雖然上面講的是漸近式重寫舊系統,但還是有少部分狀況還是重寫整個系統比較好的。就是當我們產品要整個重新設計的時候,因為我們不是只是把舊有的code變整齊而已,更多是要重新思考與汰換舊的產品。大忌是,不要搬移與重寫沒有在用的東西,如果不確定的話就想辦法去查出來,看是看request的source還是做公司級別的impact analysis。

至於怎麼做refactor,來自Slack的Maude Lemaire之前有給個talk:How to get away with refactoring。裡面講的主要是Slack之前refactor系統去增加performance的一些細節,對於沒有refactor或rejuvenation的人可以看看。

關於淘汰舊系統

不過雖然上面講了很多,但我覺得淘汰舊系統其實最難的不是重寫的部份,而是處理依賴(dependency)的部份。deprecation最痛苦的就是你不知道有沒有人在用,而就算知道有人在用,也不見得知道是誰在用你的api。

我們公司一般會使用一個叫Impact Analysis的流程去讓整個組織的stakeholder去確認改動與每個team有無關係,但做完後才是痛苦的開始,因為你要去要求他人遷移去用新的系統,或者重新討論使用的需求,但極有可能大家沒時間處理這件事。所以到最後整個搬遷的時間整個就有可能被拉的很長。我們都會開玩笑的說,這種情況就應該要做chaos engineering,直接把舊的API下掉,等大家出了error之後就自然會有動力去遷移了(誤)。

不過這裡想講的重點是,因為會有很多依賴關係的問題,所以及早的開始做這些分析與調查,及早的kick-off討論deprecation的計畫,必且同時平行的做掉那些沒有相依問題的地方,才有辦法早日脫離苦海。


上一篇
25. 懶、沒耐心、傲慢是工程師最好的美德
下一篇
27. Tech leader的重要戰略
系列文
邁向Tech Leader的成長之路30

尚未有邦友留言

立即登入留言