iT邦幫忙

2023 iThome 鐵人賽

DAY 11
3
Software Development

敏捷聖徒系列 第 11

Day 11:「偉大的航道 2/3」- 聊舊系統重構

  • 分享至 

  • xImage
  •  

另一個小故事

Tommy 打算資遣一個剛進來兩個月的新人,來找我聊這件事。我先問了原因。

「主要還是效率太差,而且做出來的東西品質也不好。」Tommy 說。
「但當時剛面試進來時,不是情況還不錯嗎?」我問。
「一拿到任務就看我們的前端系統架構不順眼,來找我說想重構,否則會改不下去。我問他要重構多久?他說兩個月。」 Tommy 說。
我當場嚇一跳問:「兩個月!那兩個月新需求怎麼辦?」
Tommy 氣 pupu 地說:「我有解釋給他聽,我說大家現在就是路過幫修、路過幫改,不然需求不收,兩個月光重構,公司會倒的。然後他就開始擺爛,後來每次 delay 時問他為什麼這麼慢,就回說誰叫我們不給他重構…」

Tommy 資遣這麼多人(?),這是我覺得資遣得最對的一位,沒有之一

關於架構(Software Architecture)

根據 Len Bass 等人在 Software Architecture in Practice 一書中的說法,架構就是「用來推理系統的一組結構」,而結構是由軟體元素、元素之間的關係,以及兩者的屬性組成。

如果也讀過 Uncle Bob 的 Clean Architecture,裡面講的「會尖叫的架構」差不多就在講同一件事。我們看一個設計稿,理應可以推論出這個系統在做什麼事情。如果推不出來,或是這個推論跟系統實際做的事差很多,那這個架構設計就有改善空間。

講到這裡,讀者是否覺得我要來反反駁 Tommy 的人事決定了?不,恰恰相反,這位新人我是支持要資遣的。上面我用的詞是「改善」,不是「重做」,原因很簡單:「價值」。

Software Architecture in Practice 書中也說了:

許多架構決策的確都是早期決定的,但並非全是如此,如「敏捷開發」就不一定。
世上沒有絕對好或絕不好的架構,架構或多或少都適用在某些地方。

一個系統的架構長成現在這個不太適合的樣貌,不代表設計它的人是笨蛋(嗯…大多數不是),而是代表這個架構當初設計時的應用場景,跟現在已經不一樣了。為什麼?因為需求會變呀!不然咧?

有人公司一開門、系統一上線第一天,在線人數就衝破百萬,因此不得不一開始就為了 DB 瓶頸而把所有系統設計成微服務 + 獨立 DB 的嗎?當然啦,如果能這樣當然很好,但這樣的公司,全世界有幾間?至少,Tommy 的公司不是。

因此,一個系統會呈現現在這個不太合適的狀態,可以說至少有 87% 以上都是因為需求天天變、天天加,經年累月下來,現在的系統功能已經跟三年前公司剛成立時很不一樣了。這時拿現在的功能去比對三年前的架構,當然覺得渾身不對勁。

然而,停止接單兩個月去「重構」,是筆者聽過最愚蠢的重構策略,沒有之一

為什麼?原因有二:

  1. 你停止接單兩個月,公司就有兩個月沒有功能產出,收入何來?到時即使讓你重構出超級驚天好棒棒架構,請問公司倒了你是要給誰用?
  2. 需求天天都在變,你今天重構出來的架構能維持合用的狀態維持多久?兩年?一年?等到你又覺得架構有點不適合了,難不成你又要再花兩個月重構一次?你在跟我開玩笑嗎?說真的,我更相信的是等你兩個月重構完,這兩個月累積的需求,跟你兩個月前覺得適合的樣貌已經又不一樣了,懂?

小規模重構

承上,現今軟體界一般認為比較好的做法是「即時且持續而不斷的小規模重構」。

為什麼?按慣例,原因有二:

  1. 當問題還很小,你需要提出的 Solution 就會相對小。
  2. 當問題還很新,造成問題的人(通常就是你自己),對問題與 Context 的理解度還很好,這時比較容易出高品質的 Solution。

於是,三年重構一次不如天天重構,不如每小時重構,不如每十分鐘重構,最好則是每兩三分鐘就重構。小病不醫,等你放到變大病,頭就很痛了。

你以為你在重構,其實你在重寫

問題來了,那如我們像 Tommy 他們,或是前文中的 Larry 一樣,啊就是已經過了三四年,系統真的已經笨重到不像話了,那該怎麼辦?

的確,這可是個大問題。

筆者曾聽 Uncle Bob 在一場演講裡說到:「所有世上問題的解決方法,都是為了解決小問題,因為大問題的解決方法只有一個,就是「拆成小問題」。」只可惜演講的連結我現在找不到了。

「軟體的架構,應該要與功能無關。」這是筆者在 Teddy Chen 課程中學到眾多觀念中,印象蠻深的一個。

既然與功能無關,那麼在修改架構的過程中,用戶就應該要無感才對。至於要怎麼達到無感。你可以像前文中 Larry 他們一樣,花 8 個月搞一個 2.0,然後一口氣推上去,讓用戶一夜之間無感換成新功能,多驚喜?

驚喜?驚嚇才對吧?

我們必須認清一件事,就是無論多麼嚴密的測試,都不能確保程式沒有 bug。測試是一個單向的指標,只能在找到問題時證明有問題,但反向的證明能力並不存在(也就是找不到問題時不代表沒問題)。因此,花大把時間做重構,並一口氣上線的「非 0 即 1」策略,並不可靠,也不經濟。這次,原因有三:

  1. 你在「重構成新系統」的過程中,因為看起來少了舊系統架構的負擔,於是你會想要大刀闊斧地全部重新寫是很合理的決定,但,這些功能當初是多少先人花了多少年的時間,一步步慢慢堆積成現在的樣貌,你一小部份人員,在幾個月內,就想做到原有的一模一樣的功能,會不會有點過度自信了?不管進來的人有多麼「菁英」。
  2. 你在重構的這幾個月中,舊系統要不要接新功能,要不要處理客戶回報的 bug?要吧?如果要,那在這幾個月中,這些工作是不是要做兩次?如果要做兩次,要叫同一個人做,還是給不同人做?如果給同一個人做,這些「菁英」的重構時間就被減少了;如果給不同人做,你要怎麼保證這兩個人會做出同樣的功能?可別忘了,舊系統肯定就是長期下來都缺少了自動化測試,你們現在才要花時間做這「功能一樣的新系統」,不是嗎?
  3. 也是最常見的,你因為舊架構太爛而重寫一份新的,但舊程式寫得太爛沒人看得懂,但它又是對的。這時 deadline 越來越近,在時間不夠與寫錯你要扛的壓力下,你會做什麼?對了,你會把這份邏輯 copy 一份 paste 在新專案上。讀者可以想像,一坨大便 copy-paste 到另一估地方,會變香嗎?很明顯不會吧?那麼,你忙了老半天,結果最重要的業務邏輯都是複製舊專案來的,我就問你在忙什麼

絞殺樹模式

如果你今天已經錯失了在原系統上慢慢重構的良機,當你評估搬到一個新系統去,成本會比較低時,比起 Larry 他們的「8 個月大重構」,與 Tommy 團隊前同事的「停工兩個月只重構不接單」方案,絞殺樹模式(Strangler Fig Mode)是一個你可以參考、安全性相對高的方式。

註:Strangler Fig Mode 我找了一會兒,還沒找到更適切的中文翻釋,只好先以字典定義直翻了。

絞殺樹是什麼?根據維基百科定義,是指一種以附生在宿主樹上開始生長,然後通過根莖的成長,用擠壓、攀抱、纏繞等方式盤剝寄樹營養,剝奪宿主樹的生存空間,從而殺死宿主樹,最後獨立生活的植物。也就是說,絞殺樹能獨立生活的那一天,就是宿主樹的死期。

回到工作場合,當你決定要採取絞殺樹模式來把舊系統替換掉的那天起,你的新系統就變成了寄生的絞殺樹,而你的舊系統就成了宿主。

接下來,你會做的事如下:

  1. 轉換:透過移植舊系統邏輯或重寫元件,識別並建立新系統中的部份元件。
  2. 共存:利用一些導流工具(如反向代理),攔截外部呼叫後,將流量重新導向新系統。其目的在逐步取代舊系統。
  3. 消除:當導到新系統的流量慢慢增加,最終完全取代掉時,關閉舊系統。

還記得上面 Uncle Bob 說的嗎?會需要這麼久的重構就代表你的系統大又重,因此,為了解決這個大問題,你一定要做的事就是把它拆小。過程中你會透過不斷重複上述 1 與 2 的步驟,慢慢地剝奪「宿主樹」的生存空間。亦即,讓你的舊系統越來越少人用。直到有一天,舊系統已經完全沒有人用了,這時等三天看有沒有人叫。沒人叫,代表新系統已經可以獨立生存,這時,你就可以列隊脫帽敬禮,向舊系統說聲「辛苦了」,然後關閉它的電源。

如果時光能重來

回到一開始 Larry 的故事,上線日維護 8 小時所造成的損失是完全可以避免的。如果他們可以用絞殺樹的模式來穩定的重構,他們大可以每兩週固定置換掉一小部份,或是一個元件一個元件慢慢置換。如此一來,萬一哪天出了事,那麼我們大可以馬上把流量切回舊系統,就不用凌晨 4 點把 RD 挖起來處理,QA 也不用大清早的起來陪維運人員更版了。

謎之聲:「睡飽才有力氣幹活兒!」

Reference

  1. Len Bass, Paul Clements, and Rick Kazman, Software Architecture in Practice (SEI Series in Software Engineering) 4th Edition, Addison-Wesley Professional, 2021
  2. Robert C. Martin, 無瑕的程式碼-整潔的軟體設計與架構篇 (Clean Architecture: A Craftsman's Guide to Software Structure and Design), 博碩文化, 2018
  3. Martin Fowler, StranglerFigApplication, https://martinfowler.com/bliki/StranglerFigApplication.html
  4. 絞殺植物. (2023, March 14). In Wikipedia. https://zh.wikipedia.org/wiki/%E7%B5%9E%E6%AE%BA%E6%A4%8D%E7%89%A9

上一篇
Day 10:「偉大的航道 1/3」- 這是一個驚心動魄的故事
下一篇
Day 12:「偉大的航道 3/3」- 聊多團隊協作與團隊組成
系列文
敏捷聖徒30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言