Tommy 打算資遣一個剛進來兩個月的新人,來找我聊這件事。我先問了原因。
「主要還是效率太差,而且做出來的東西品質也不好。」Tommy 說。
「但當時剛面試進來時,不是情況還不錯嗎?」我問。
「一拿到任務就看我們的前端系統架構不順眼,來找我說想重構,否則會改不下去。我問他要重構多久?他說兩個月。」 Tommy 說。
我當場嚇一跳問:「兩個月!那兩個月新需求怎麼辦?」
Tommy 氣 pupu 地說:「我有解釋給他聽,我說大家現在就是路過幫修、路過幫改,不然需求不收,兩個月光重構,公司會倒的。然後他就開始擺爛,後來每次 delay 時問他為什麼這麼慢,就回說誰叫我們不給他重構…」
Tommy 資遣這麼多人(?),這是我覺得資遣得最對的一位,沒有之一。
根據 Len Bass 等人在 Software Architecture in Practice 一書中的說法,架構就是「用來推理系統的一組結構」,而結構是由軟體元素、元素之間的關係,以及兩者的屬性組成。
如果也讀過 Uncle Bob 的 Clean Architecture,裡面講的「會尖叫的架構」差不多就在講同一件事。我們看一個設計稿,理應可以推論出這個系統在做什麼事情。如果推不出來,或是這個推論跟系統實際做的事差很多,那這個架構設計就有改善空間。
講到這裡,讀者是否覺得我要來反反駁 Tommy 的人事決定了?不,恰恰相反,這位新人我是支持要資遣的。上面我用的詞是「改善」,不是「重做」,原因很簡單:「價值」。
Software Architecture in Practice 書中也說了:
許多架構決策的確都是早期決定的,但並非全是如此,如「敏捷開發」就不一定。
世上沒有絕對好或絕不好的架構,架構或多或少都適用在某些地方。
一個系統的架構長成現在這個不太適合的樣貌,不代表設計它的人是笨蛋(嗯…大多數不是),而是代表這個架構當初設計時的應用場景,跟現在已經不一樣了。為什麼?因為需求會變呀!不然咧?
有人公司一開門、系統一上線第一天,在線人數就衝破百萬,因此不得不一開始就為了 DB 瓶頸而把所有系統設計成微服務 + 獨立 DB 的嗎?當然啦,如果能這樣當然很好,但這樣的公司,全世界有幾間?至少,Tommy 的公司不是。
因此,一個系統會呈現現在這個不太合適的狀態,可以說至少有 87% 以上都是因為需求天天變、天天加,經年累月下來,現在的系統功能已經跟三年前公司剛成立時很不一樣了。這時拿現在的功能去比對三年前的架構,當然覺得渾身不對勁。
然而,停止接單兩個月去「重構」,是筆者聽過最愚蠢的重構策略,沒有之一。
為什麼?原因有二:
承上,現今軟體界一般認為比較好的做法是「即時且持續而不斷的小規模重構」。
為什麼?按慣例,原因有二:
於是,三年重構一次不如天天重構,不如每小時重構,不如每十分鐘重構,最好則是每兩三分鐘就重構。小病不醫,等你放到變大病,頭就很痛了。
問題來了,那如我們像 Tommy 他們,或是前文中的 Larry 一樣,啊就是已經過了三四年,系統真的已經笨重到不像話了,那該怎麼辦?
的確,這可是個大問題。
筆者曾聽 Uncle Bob 在一場演講裡說到:「所有世上問題的解決方法,都是為了解決小問題,因為大問題的解決方法只有一個,就是「拆成小問題」。」只可惜演講的連結我現在找不到了。
「軟體的架構,應該要與功能無關。」這是筆者在 Teddy Chen 課程中學到眾多觀念中,印象蠻深的一個。
既然與功能無關,那麼在修改架構的過程中,用戶就應該要無感才對。至於要怎麼達到無感。你可以像前文中 Larry 他們一樣,花 8 個月搞一個 2.0,然後一口氣推上去,讓用戶一夜之間無感換成新功能,多驚喜?
驚喜?驚嚇才對吧?
我們必須認清一件事,就是無論多麼嚴密的測試,都不能確保程式沒有 bug。測試是一個單向的指標,只能在找到問題時證明有問題,但反向的證明能力並不存在(也就是找不到問題時不代表沒問題)。因此,花大把時間做重構,並一口氣上線的「非 0 即 1」策略,並不可靠,也不經濟。這次,原因有三:
如果你今天已經錯失了在原系統上慢慢重構的良機,當你評估搬到一個新系統去,成本會比較低時,比起 Larry 他們的「8 個月大重構」,與 Tommy 團隊前同事的「停工兩個月只重構不接單」方案,絞殺樹模式(Strangler Fig Mode)是一個你可以參考、安全性相對高的方式。
註:Strangler Fig Mode 我找了一會兒,還沒找到更適切的中文翻釋,只好先以字典定義直翻了。
絞殺樹是什麼?根據維基百科定義,是指一種以附生在宿主樹上開始生長,然後通過根莖的成長,用擠壓、攀抱、纏繞等方式盤剝寄樹營養,剝奪宿主樹的生存空間,從而殺死宿主樹,最後獨立生活的植物。也就是說,絞殺樹能獨立生活的那一天,就是宿主樹的死期。
回到工作場合,當你決定要採取絞殺樹模式來把舊系統替換掉的那天起,你的新系統就變成了寄生的絞殺樹,而你的舊系統就成了宿主。
接下來,你會做的事如下:
還記得上面 Uncle Bob 說的嗎?會需要這麼久的重構就代表你的系統大又重,因此,為了解決這個大問題,你一定要做的事就是把它拆小。過程中你會透過不斷重複上述 1 與 2 的步驟,慢慢地剝奪「宿主樹」的生存空間。亦即,讓你的舊系統越來越少人用。直到有一天,舊系統已經完全沒有人用了,這時等三天看有沒有人叫。沒人叫,代表新系統已經可以獨立生存,這時,你就可以列隊脫帽敬禮,向舊系統說聲「辛苦了」,然後關閉它的電源。
回到一開始 Larry 的故事,上線日維護 8 小時所造成的損失是完全可以避免的。如果他們可以用絞殺樹的模式來穩定的重構,他們大可以每兩週固定置換掉一小部份,或是一個元件一個元件慢慢置換。如此一來,萬一哪天出了事,那麼我們大可以馬上把流量切回舊系統,就不用凌晨 4 點把 RD 挖起來處理,QA 也不用大清早的起來陪維運人員更版了。
謎之聲:「睡飽才有力氣幹活兒!」