本文同步刊載於個人連載網站
Day 28 寫到,在開始想系統要做什麼以前,我現在會先看人到底怎麼工作。
但把人的工作看懂之後,還不能直接進入實作。
一件工作真的要交給系統,接下來還會一路出現另一批問題。
以前很多問題,是做到一半、甚至撞牆之後,我才知道它們存在。
現在我開始知道,有幾個問題不能不問。
以前我很容易從功能開始想。
我要一個切換功能、一個上傳功能、一個預約功能。
現在看到一個功能需求,我會先多問一層:
這件事情如果真的成立,哪些東西不能跟著變錯?
前面寫過 QA 測試帳號的例子。
表面上的需求只是讓同一個帳號切換不同業務情境,但真的做進系統後,不能因為測試方便,就讓 QA 變成另一個正式使用者,也不能繞過原本的權限規則。
不同頁面看到的資料,也必須站在同一個業務情境裡。
這時候我需要理解的,就不再只是「切換按鈕怎麼做」。
真正的問題變成:
這個功能成立時,系統必須一直維持哪些條件?
這些條件先看清楚,後面的工程設計才有依據。
而下一個問題也會跟著出現。
一件功能到了系統裡,通常不只落在一個地方。
使用者看起來只是在操作同一套產品,背後卻可能同時牽涉前端、後端、資料庫,甚至另外的服務。
這時候我會開始問:
這件事情真正應該在哪裡被守住?
例如權限。
畫面上不顯示某個按鈕,可以避免使用者誤操作,但真正不能讓他執行的限制,不能只靠前端畫面維持。
或者某一種工作和主要後端處理的事情性質差很多,也可能需要再問:
它是不是值得另外拆出去?
如果拆開,會增加哪些溝通和維護成本?
我不一定立刻知道答案。
但我現在比較容易先想到:
功能做得出來,還不代表責任放對地方。
而責任一旦拆開,問題也沒有結束。
前端、後端和其他服務可以分開負責不同工作,不同 repo 也可以各自管理。
但對使用者來說,它們仍然共同完成同一件事。
所以不能只確認:
每一個部分自己有沒有正常。
還要確認:
它們彼此之間原本約好的事情,有沒有一起維持。
前後端交換的資料格式是一種約定。
不同 repo 對同一個功能的理解也是一種約定。
一邊修改之後,另一邊如果還留在舊的理解裡,每個部分單獨看可能都沒有問題,整套產品接起來卻會壞掉。
這也是我後來會把跨 repo 的共同規格、架構資訊和重要決策留下來的原因。
責任拆開,是為了讓不同部分可以各自處理適合自己的事情。
但產品不能因此也被切成彼此不知道對方在做什麼的幾塊。
拆開之後,仍然要維持共同的產品脈絡和彼此的約定。
做到這裡,還剩下一個問題。
前面說好要保證的事情、責任怎麼分、彼此怎麼配合,都已經整理清楚了。
那我怎麼知道最後真的有做到?
以前功能跑得動,我很容易把它理解成接近完成。
現在我會再問:
我憑什麼相信它真的成立?
目前我的做法,是從不同層次交叉確認。
規格先確認這次到底要做什麼,以及哪些條件不能被破壞。
測試持續檢查那些已經明確定義下來的行為。
review 再看實作有沒有偏離原本設計,或者破壞既有的系統分工與工程方式。
最後我自己實際操作,確認這些功能放回真正的工作情境後,人是不是能合理地把事情完成。
這幾層不是同一件事情重複檢查很多次。
它們是在回答不同問題。
而我現在也很清楚,這套做法還沒有替我解決所有可靠性問題。
我自己人工操作,目前主要還是確認 Happy Path。
至於哪些例外、邊界條件、角色與資料狀態一定要驗,以及做到什麼程度才算足夠,我還沒有完整的 QA 判斷能力。
所以我現在至少知道:
「做完之後怎麼證明它成立」本身,就是工程問題的一部分。
回頭看,我覺得真正改變的,不只是我多知道了一些工程名詞。
而是看到一件工作準備進入系統時,現在有幾個問題會一路接著出現:
這件事情要保證什麼?
誰應該負責把它守住?
責任拆開之後,彼此怎麼維持約定?
最後,我拿什麼證據相信前面的判斷真的被做進系統?
這幾個問題對我來說,已經不再是分散的工程知識。
它們更像同一條線。
先知道什麼不能弄錯,再決定由誰負責;責任拆開後,要讓不同部分繼續維持共同的理解;最後,再回頭確認這些判斷有沒有真的落進實作。
我不一定每一題都有答案,也不是每一個工程概念都已經形成成熟的判準。
但以前很多事情,是撞到問題之後我才知道原來需要問。
現在,有些問題已經會在實作以前自己出現。
我開始知道,一套系統有哪些事情不能不問。
而知道這些問題需要被判斷,和我自己需要理解多少程式碼才能參與這些判斷,仍然不是同一件事。
最後一篇,我想回到這個系列一開始留下的問題:
AI 都會寫程式了,Coding 到底要懂多深?