我們用 SMART——Specific(具體)、Measurable(可衡量)、Achievable(可達成)、Relevant(具關聯)、Time-bound(有時限)——把每個故事拆成五天,作為每次動手造輪子前的五個檢查問題。
本篇是故事一「客戶要加個按鈕切換 LED 呼吸燈,一個月後 RD 還在談 CMSIS 與 Clean Code」的 Relevant 篇:這項工作與客戶價值、專案目標及交付有什麼關係?
本篇定位:避免把這個系列寫成反架構、反 Clean Code,真正要指認的是技術工作與專案目標失去關聯。
散會前那句「就這樣算了嗎」我想了很久。問的人不是想拖延交付,他是那個月裡讀最多規範、畫最多圖的人,真心認為那份韌體應該變好。
而且他說的每一句都對。CMSIS(Common Microcontroller Software Interface Standard,通用微控制器軟體介面標準)是 Arm 定義、以 Cortex-M 為主的一組軟體介面,這次沾得上邊的有兩支。CMSIS-Core 統一的是核心這一層:NVIC、SysTick、SCB 與 MPU/FPU 的暫存器定義與存取函式、系統例外名稱、SystemInit() 與 SystemCoreClock 慣例,以及 device header 與 startup 檔的組織方式;它讓核心相關的起手式跨廠牌一致,碰到各家自己的週邊,還是得回到廠商 HAL。CMSIS-Driver 則替週邊定義標準介面,讓上層不必綁死某一家的驅動寫法。Clean Code 那套主張也禁得起檢驗:命名說得出意圖、函式短到一眼看完、副作用收斂。
我當時答不上來:要否定它們,得說出一句我自己都不相信的話;要贊成它們,又得解釋為什麼贊成了一個月,按鈕還是不會動。
後來我才想清楚:這道題不該用「同意」或「反對」回答。CMSIS 與 Clean Code 是不是好東西,和「它們該不該出現在這張工單上」是兩個獨立的問題。
Relevant 問的不是「這個技術好不好」,而是「這件工作和這次交付是什麼關係」。CMSIS 對齊在新專案起步、要移植到另一顆 MCU、要導入 CMSIS-Driver 生態時,解的是專案真的會遇到的問題——那時候「跨廠牌一致的核心起手式」不是美感,是省下來的移植工。Clean Code 同理:每季都要被改的邏輯整理到看得懂,省下的是往後每次修改的時間。
問題是,這次不屬於上面任何一種情境。這是一份已量產、行為長期穩定、只多一顆按鍵的韌體。重構的收益都寫在「下一次修改」上,而這裡沒有下一次修改在排隊:沒有移植計畫,也沒有新功能等著長出來。收益找不到收款人,成本卻由這次交付全額支付。
於是「看起來很專業」和「對交付有幫助」之間裂出一道很寬的縫,我們整個月都站在裡面。分層圖、命名規範、框架介面每一項都看得見進度,卻不會讓驗收表上的任何一列變綠。而且這種工作永遠不會失敗:畫圖不會被客戶按壞,規範不會在現場當機;接進主迴圈的按鍵事件卻隨時可能撞見意外。愈接近交付,工作愈可能失敗,人於是停在最安全的那一段,並替它找一個最負責的名字。
我後來替技術改善分類的方法很土:翻譯成一句「如果不做,這次交付會發生什麼」。
翻得出具體後果的,就是這次該做的品質工作。按鍵事件在中斷裡更新燈效狀態,主迴圈同時讀同一份狀態做 LED 更新——中斷與主迴圈共用一個變數:編譯器可能把它快取在暫存器裡而看不到中斷改過的值;讀寫若不是單一不可分割的動作,還可能讀到改到一半的狀態。處置很具體:共用變數宣告成 volatile,成對更新的地方用臨界區保護,短暫關中斷或用旗標交接。偶發跳態的除錯成本沒人想承擔,這項該在這次做掉。按鍵邏輯若和延時攪在一起,除了拿手指按之外沒辦法驗證,而驗收表上那幾列需要它。
翻不出具體後果、只說得出「比較乾淨」的,就另開工單、另訂驗收。
另一個角度是站在三種人的位置各問一次:客戶要的是按鈕的行為改變,產品要的是能出貨又不影響既有機種,維護者要的是日後找得到那段狀態轉移。三種人都受益的才是必要品質。
不屬於這次的部分一定要留下紀錄,否則下次還會從頭吵一遍。這件事有個現成格式:架構決策紀錄(ADR,Architecture Decision Record),一頁四欄——背景、決定(以最小變更完成,不全面重構)、理由(回歸風險與交付時程),以及什麼條件下該重新評估(下次移植到新 MCU,或既有結構真的擋住某個功能)。它把「我們不做」從默契變成有署名、可被日後推翻的決定。那位同事要的就是這個:一個有署名的答覆,和一個重新拿出來談的時機。
指認一項技術工作是否失焦,不需要評價那項技術本身。CMSIS 是好的標準,Clean Code 是好的習慣,這兩句話完全成立;成立之後,它們依然沒有回答「這張工單這次要交什麼」。
好架構應該讓團隊更快、更安全地把需求做出來;當它變成需求必須排隊等待的入口,方向就反了——這不是架構的錯,是我們把手段擺到了目的前面。分辨的方法很便宜:說出「如果不做,這次交付會發生什麼」,說得出來就做,說不出來就寫進架構決策紀錄。
但還有一個問題沒解決:就算大家都同意先交付、後改善,「先」和「後」之間隔多久?沒有刻度的先後,在下週會議上還是會被溫柔地往後挪一格。