絞殺榕模式
Strangler Fig 是一種寄生植物,會逐漸纏繞並吸取宿主的營養,最終讓宿主枯萎,自己蓬勃生長取而代之,謂之「絞殺」。因此,絞殺榕模式的核心也可以用一句話概括:「逐步生長,逐步接管,逐步替換,逐步移除。」
這是一個蠻有意思的設計模式,面向的核心場景是舊業務老舊、重構困難尾大不掉,而又想引入新的現代化技術時,就會採用這個模式。其核心關鍵是最大化相容和隔離,保證新功能的邊界嚴格控制在新功能処,而對外暴露的是相容的舊介面。舊系統將在可預期的時間內和新系統長期共存,直到新系統徹底且安全的取代了所有舊系統實現的功能。
比起徹底推導老舊系統的大爆炸重寫(Big Bang Rewrite),逐步且漸進的替代顯然更加安全和低成本。和這個設計模式搭配的一般都是微服務,將舊系統隔離在一個代理層後,此前一切照舊,此後一切從新。出現問題時代理層也會成為風險隔離的護盾,而不至於牽一髮動全身,導致重構不成,舊功能也全面失效。放在前端則是以孤島模式為主的微前端——本質上是徹底模組化的容器思想。因為本身就沒什麼耦合,也能做到最小化影響。它天然的模組化設計架構,也讓測試非常方便。內外不耦合,輸入輸出明確,測起來也很輕鬆。
前端重構的流程就可以是這樣:對舊專案以微前端的形式逐步引入單一的新功能模組,內部完全採用Angular或者React這種現代化框架構建。同時,保證其最終的編譯產物和呼叫可以在整體的舊系統下相容。對舊的系統來説,它不會看到這裡出現了「新東西」,而是「一切照常」(就跟被寄生的宿主感覺不到一樣,但實際已經在流失營養)。核心的關鍵關鍵是保證整體的遷移過程的可靠性和可控性,控制問題在限定範圍內,做好隨時回退的便捷入口,最好是一鍵解除安裝。
其次,不能光顧著功能上隔離,也要保證資料上的隔離。在資料處理上需要設定一個防腐層,以免舊資料結構汙染到新模組,導致嚴重的隱性資料依賴問題。比如某個依賴於舊功能的特殊欄位,如果新模組直接取,那未來移除舊模組後這裡就會直接炸。
特別就前端來説,CSS上的隔離也至關重要。這個不只是舊系統的全局樣式會汙染新系統的樣式,還有反過來的,比如Tailwind CSS這種UI庫就可能存在CSS Reset,一旦我把它掛到舊系統的介面除,那就可能導致其順著整個管線上去把舊系統的樣式也全改了。所以這算是一個需要考慮的邊界問題。
不過,若是舊業務的部分內容耦合嚴重,有大量狀態依賴,那就不適合強行往裡面塞新架構。能做到邊界清晰永遠是替換的前提,雙方只用契約結構進行交流。新的部分不應該大量和舊頁面共享狀態,否則舊的一拆,新的就全完。