2017 年成立的漸強實驗室,以打造世界級的 B2B 軟體服務公司為目標,專注於透過導入各種軟體服務來協助企業數位轉型,成立不滿兩年就已獲得跨國 AI 集團 iKala 的投資,在今年成立滿五週年前,漸強實驗室已是 LINE 唯一金級技術合作夥伴,同時也是全台橫跨最多垂直生態鏈,服務超過 400 家品牌商的 Martech 生態圈重要領頭羊。
前言
大家可能都遇過公司想要導入一些新技術或是新方法來解決團隊的問題,不論是公司驅動或是內部成員發起,導入的過程通常會面對重重關卡,而且失敗的例子也是時有所聞。本篇文章是漸強實驗室工程團隊成功導入 Clean Architecture 與 DDD 的架構,改善程式碼品質並提升開發效率的經驗分享:從發現問題、尋找解法、導入技術、到成功執行解決問題的過程。
先打預防針:本篇文章不會提到技術相關的深入內容,主要在探討如何導入一個新技術方法的過程,有哪些步驟? 效果如何? 以及學習到的經驗!
起因
時間回到 2021 年初,公司的產品 MAAC (https://cresclab.com) 已經在台灣市場上站穩龍頭位置,但是快速成長的代價,免不了技術債的堆積。隨之而來的是越來越多我們想推出的新功能,會因為技術債而需要被妥協的情況,另外團隊開發速度也越來越慢、工程師們開始對估算開發時程缺少信心,當時這是一個走了兩年左右的專案,工程團隊開始對於產品上日趨複雜的商業邏輯感到頭痛。
定義問題
產品上由於功能的開發與各種第三方串接甚至是客製化功能,商業邏輯越來越複雜,過去開發規範除了遵守框架規範外,其餘的規範比較鬆散,主要透過 code review 來達成共識。且過去有許多嘗試性的需求,商業邏輯堆疊越來越猖狂,各種程式碼片段東插西插,導致單元測試變得難以撰寫;越大範圍的改動,受影響範圍的評估變得相當困難。面對技術債當然是每個團隊的課題,當時我們認為應該要有一個更適合的 codebase 開發架構,幫助大家有效的梳理商業邏輯,讓新的部份不要再重蹈覆徹,舊的部份也能夠有系統地還上債務,所以定義了兩個要解決的問題:
1. Codebase 的管理架構要能夠支撐更大更複雜的擴張
2. 如何有效地維護以及管理複雜的商業邏輯
如何解決
關於解決這兩件事情我們開始了一些研究,最後我們認為在原本的框架中,透過 Clean Architecture 分層的概念來重新架構 codebase,然後結合 DDD 的概念來對複雜的商業邏輯建模,應該是條正確的道路。
於是我從最熟悉且邏輯最複雜的後端服務開始嘗試,公司後端使用的技術棧主要是透過 python 的 Django + Celery 框架,我們開始建立空白專案在本地環境嘗試,參考許多的網路文章,試著建立一個可相容現在專案且可擴展的分層架構。當時我們認為在團隊沒有相關經驗的情況下,直接整套 DDD 導入的成功機率應該是零。所以如何務實的,在框架上結合 Clean Architecture 配上 DDD 的概念有效的解決問題,是我們著眼的重點。
有了初步的結論後就開始導入的旅程~
導入的過程
大致上可以把導入過程分成四個階段:
1. 研究解決方法:
如上述,最初兩個月我們開始定義問題,且研究如何解決,重點在降低上手門檻,以及務實解決問題。
2. 種下導入的種子:
之後,開始跟團隊部分成員討論導入這些概念的構想,並且給了整個團隊幾場相關知識概念的分享並附上簡單的 demo 來幫助理解。在這個過程中,可以跟已經知道這些概念的成員做知識上的對齊,也讓沒聽過這些知識的成員有一個初始的概念。這是非常重要的一步,導入這種偏重心法的東西,重點要讓團隊理解方法帶來的好處,比起給方法先照著做,讓團隊成員能理解導入後的好處,會有驅動力上的不同。
3. 技術導入也需要的 MVP:
接下來開始對某一個後端的小專案,切了一個 branch,直接將整個專案試著改寫成新架構的樣子,來當成實際情境上的 demo,並且撰寫文件跟大家討論如何運用這些概念,並且擴展實作到現在的專案上,同時跟部分有興趣的成員在大專案上的小功能上也嘗試使用。這個時期是碰撞最多火花的,也是導入成敗的關鍵,透過 MVP 的概念來搜集團隊的回饋,然後在提出的架構上持續做調整。
這些調整非常重要,有提到務實的運用方法解決問題才是關鍵。所以在整個過程中,必須解釋為何把架構這樣設計、好處跟壞處是什麼,同時集合團隊成員的意見,根據大家過去開發上的經驗來討論。可能有當初沒考慮到的使用情境,也可能是大家認為還可以再簡化的做法,這是一個開始讓成員們體驗跟形成共識的過程,集合大家意見且在方法上做調整,可以讓這個架構更符合團隊的需求。
4. 實行與迭代:
開始有累積一些使用心得與共識後,開始在後端專案上全面實行,並且持續對遇到沒定義好的狀況做討論跟解決,同時訂了一些重構上的方案,基本上新架構在原本的 codebase 上是完全跟舊的 code 隔離的,所以當開發上遇到會影響到舊的 code 的時候,就將舊的 code 部分重構成新的設計,一開始實際執行的時候,因為有上手跟學習的成本,而影響一些開發進度,但大概在大家都執行過一次開發後,速度上基本就恢復正常。
結果與影響
結果
- 分層架構對測試的幫助非常顯著,新架構有九成左右的測試覆蓋率。
- 在新架構上的開發,工程師們普遍覺得開發體驗上有所提升,不管是測試或是商業邏輯的組織,都有正面的回饋。
- 遇到舊 code 的部分 refactor 成效不如想像好,主要是 refactor 的時間與開發時程上的取捨。
- 架構設計最後寫成 guideline,讓新加入的人可以學習。
- 就目前來看,不論是擴展性跟商業邏輯的組織,當初定義的問題都有獲得很大的改善。
影響
- 新加入的工程師需要花多一點力氣入門,直接影響新人上手開發的時間,需要再多花時間在這方面的知識上做同步。
- 開始使用學習了之後,驅動大家接觸這方面的知識,團隊成員都會持續在這些方法上學習跟鑽研,有效的提升團隊軟體架構能力。
心得分享
當時是八人小團隊,且大家都有一定的開發經驗,溝通成本並沒有太高,再者當時向上負責的對象是 CEO ,但 CEO 並不管技術細節,沒有向上溝通的成本,這點是大家要注意的,因為向上溝通這件事情會直接影響導入新方法的成敗。
導入的過程其實蠻冗長的,一方面是有原本的事情要做,一方面是規劃上有種下種子讓知識發酵的過程,就結果來看,因為知識發酵的過程,兩三個禮拜就會看得到,主要還是要調節原本開發的節奏,讓成員有時間心力來接觸新知跟理解,這點時間的規劃上並沒有做得很好,不能期待所有人都會在工作外的時間接觸這些東西。
會特別利用種子讓知識發酵是這次導入會成功的一大原因,先用散播知識的方式,讓大家接觸這項技術,知道它的用途與好處,不只對日後導入有減少排斥的幫助,還會讓團隊在先理解之後帶來更多知識上的碰撞,加大導入過程的回饋進而提高成功率。
導入技術或是流程的時候,追求的是讓團隊成員自動自發地發展起來,重點首先放在要讓團隊理解這個技術跟流程到底在幹嘛,然後是讓團隊成員參與去做一些回饋跟決定,這樣可以提高成員的 ownership,同時保持彈性接收回饋持續調整跟優化,讓導入的東西是活的可變的,這樣大家才有心力去發展它。
當然還是有遇到阻力,新的方法的推動意味著開發習慣上的改變,可能是開發上要遵守的事情變多,或是寫 code 的習慣要重新調整等等,基本上這方面的阻力還是靠溝通,確保大家對遇到的問題有共識,並且對解決的方法有信心。
最後
導入的過程中,我從 Clean Architecture 書中截了兩段話,跟團隊成員分享,我覺得非常深刻,這邊也跟大家來分享:
以及
身為開發者的你是不是也心有戚戚焉呢?
最後,感謝你的閱讀。
若你看完我們的分享,對我們的工作文化有興趣的話,🙌 一起加入漸強實驗室 🙌 成為我們未來的工作夥伴吧!
留言