iT邦幫忙

2026 iThome 鐵人賽

DAY 26
0

同一份完成條件,存在大神腦裡叫通靈,寫在牆上叫 AC;內容可能一模一樣,讀取權限差了一整個團隊。


第一版草稿,五分鐘就寫完了

昨天那場對話散會前,白板上留著一排問出來的答案:金流是非同步的、七天內未出貨才能直接退、財務的痛在對帳。最後一句結論是:把它們寫下來——不要靠通靈。

今天就是來寫的。

PM 把昨天的筆記整理了一下,五分鐘後念出第一版:

「退款功能正常運作,操作流暢,狀態顯示正確。」

平心而論,這不是偷懶。這就是大家習慣的寫法,每個人聽了都點頭——危險的地方正在這裡:每個人點頭點的,是自己腦中那個版本的「正常」。

年輕的後端工程師舉手:「驗收那天,這句話要怎麼檢查?」

「什麼意思?」

「誰、做什麼動作、看到什麼,算通過?看到什麼,算不通過?這句我讀了三遍,還是不知道程式要寫成什麼樣子才叫『正確』。」

會議室安靜了兩秒。跟 Day 18 那場安靜不一樣——那次是發現三週的工蓋在錯的假設上;這次是發現,再寫十句這種話,三週後就會回到同一個房間。

於是整個下午只做一件事:把白板上每一個「怎樣算成功」,改寫成一句可以檢查的話。


一個下午,五句話

改寫的過程比想像中吵,因為每改一句,就逼出一個還沒回答的問題。

第一句。「按下退款後顯示結果」——顯示什麼結果?金流是非同步的,按下去那一秒,全世界還沒有人知道結果。所以第一句只能誠實地寫:按下退款後,這筆訂單顯示「處理中」;金流確認之前,畫面不出現「成功」兩個字。第三部最早那顆按鈕,按下去只有一種結局,這句就是衝著它來的。

第二句。那「處理中」亮到什麼時候?等金流商的確認通知。確認之後誰要知道?申請退款的客服。所以:收到確認成功的通知後,狀態變「成功」,客服收到通知。

第三句是失敗。第三部的畫面拖到聯調後期才長出「失敗」這一格,這次它在動工前就有位置:金流確認失敗後,狀態變「失敗」,客服看得到、而且可以重試。

第四句是金流串接工程師開的口:「webhook 會重送,同一筆通知可能來兩次。」這句話他在 Day 18 的聯調會議上說過一次,沒有人接話,會議記錄上也沒有這一行。上線後一筆訂單被標記兩次退款,就是那一行沉默的利息。這次,這句話當場變成一條 AC:同一筆退款通知收到兩次,錢只退一次、狀態只變一次。

第五句是替財務寫的。金流商日結、對帳檔隔天才有,所以這句話的時態是隔天:財務拿對帳檔核對,這筆退款在我們系統與金流商的紀錄一致。第三部月底那場對不上的帳,追的就是這一句的缺席。

散會時有人自嘲:「我們一個下午的產出,是五句中文。」

另一個人接:「第三部我們三週產出幾千行程式,沒有一行知道自己怎樣算完成。」

拿 Day 23 的目標句來對,會發現這五句不是新需求:「操作後能明確知道退款成功或失敗」攤開來就是前四句,「財務能對得上帳」就是第五句。AC 沒有增加任何東西,它只是把目標句磨到可以拿來驗收的細度。


「可以檢查」是唯一的門檻

一句話是不是 AC,判準只有一個:

拿著這句話站在系統前面,做完動作,答案是「過」或「不過」——而且換任何一個人來做,答案相同。

「正常」「流暢」「正確」過不了這一關。形容詞是通靈的溫床:每個人腦中都有自己的版本,而且每個版本單獨看都有道理。Day 10 說過,沒有 AC 的時候「完成」不會消失,它會分裂——工程師一版、PM 一版、客戶一版。第二部靠大神在交付前一週,一個人把所有版本悄悄對齊;第三部沒有大神,版本在上線之後、當著客戶的面對齊,用最貴的方式。

把「怎樣算好」寫下來這件事,瀑布與敏捷都有位置:瀑布把驗收依據綁在 Baseline 上,敏捷把它貼在每一條 Story 上。形式的差別 Day 10 講過,不重講。今天真正要補的是另一件事:

AC 是把每一層「成功」變成可檢查的句子;寫的過程本身,就在逼問完成語意。

Day 18 那天,團隊用一場鴉雀無聲的聯調,學到那條不等式:

HTTP 200
≠ refund accepted(金流商受理這筆退款申請)
≠ payment reversed(錢真的被退回)
≠ state confirmed(我們的系統確認並更新狀態)
≠ user goal achieved(客戶拿回錢,而且知道拿回了)

當時它是一張驗屍報告:五層「成功」,動工前回答了零層。今天,同一條不等式變成施工圖,每一層都有了可以檢查的句子:

HTTP 200
→ 按下退款後顯示「處理中」,不冒充「成功」

refund accepted
→ 「處理中」持續亮著,直到金流給出結果

payment reversed
→ 收到確認通知,狀態才變「成功」;失敗就變「失敗」、可重試

state confirmed
→ 同一筆通知來兩次,只退一次;隔天對帳檔核對一致

user goal achieved
→ 操作的客服收到通知、看得到最終結果
(這一輪的「使用者」照 Day 23 的目標句,是替客戶發動退款的客服)

Day 18 的完成語意定義表問的是「每一層由誰、用什麼機制確認」;AC 做的事,是把每一個答案釘成驗收當天可以執行的句子。寫不出句子的那一層,就是還沒想清楚的那一層。第三部的 webhook 就是這樣漏掉的——不是沒人知道,是流程裡沒有任何一個位置,逼大家把它寫成一句話。


這份清單,上次住在誰的腦裡

Day 10 的場景值得倒回去看一眼:交付前一週,資深工程師一個人「再修一輪」——空值、位數、檔名、loading。那是一份又準又完整的 AC,準到連 Non-goal 都有。只是儲存位置是他的腦,讀取權限只有他自己,執行時間是驗收前一週。

今天牆上這五句話,做的是同一件事,差別只有三個欄位:儲存位置,從人腦變成牆上;讀取權限,從一個人變成所有人;執行時間,從驗收前一週,提前到動工之前。

Day 18 還說過,大神真正的功能不只是知道答案,而是會在對的時間把對的問題問出來。今天問出「這句話要怎麼檢查」的,是那位年輕的後端工程師——他沒有變成大神,他只是站上了流程裡本來就該存在的一個位置。寫 AC 這個動作,就是把「對的時間」釘死在動工之前:一句寫不成可檢查的話,當場現形,不必等三週後的聯調,也不必等某個人剛好路過。

順帶一提,資深工程師仍然在另一個專案救火。今天一整個下午,沒有人提起他。


這次到底誰在吸收代價?

老規矩。這個下午沒有寫任何程式,看板上沒有一張 Ticket 移動——用第三部的標準看,這是「零進度」的一天。帳怎麼記?

Scope       □   邊界照 Day 24 定案,一項沒動
Time        ■   一個下午換五句話   ← 有意識地付,買的是驗收當天沒有驚喜
Cost        □
Quality     □   失敗路徑與重送防護,動工前就有了判準
Risk        □   第三部炸過的兩顆雷,這次動工前就寫進了條件
人          □   ← 這次沒有人需要通靈

對照 Day 10:同樣一份「怎樣算好」,第二部的記帳方式是人 ■——大神一個人的驗收預演,帳面乾淨得看不出任何代價。今天的帳難看多了:整個團隊、一整個下午、產出五句中文。但這五句誰來讀答案都一樣,下週任何人請假,它們都還在牆上。

通靈很便宜,直到通靈的人不在場;寫下來很貴,但貴得清清楚楚,而且一次付清。


今日 Artifact|退款 AC 實例

把今天的五句話原樣留下。它是這個案子的實例;把「退款」換成你手上任何一個非同步動作,文法照用:

□ 受理|客服按下「退款」後,訂單顯示「處理中」——
       金流確認之前,畫面不出現「成功」
□ 成功|收到金流確認成功的通知後,狀態變「成功」,
       申請的客服收到通知
□ 失敗|金流確認失敗後,狀態變「失敗」,
       客服看得到、並且可以重試
□ 重複|同一筆退款通知收到兩次,
       錢只退一次、狀態只變一次
□ 對帳|退款隔天,財務拿金流商對帳檔核對,
       兩邊紀錄一致

五句是同一種文法:誰、在什麼時點、看到什麼。寫不出這種句子的功能,不是太難寫,是還沒想清楚怎樣算完成——Day 10 結尾那個問題,今天原封不動地適用:那麼現在正在動工的,到底是什麼?


今日一句

AC 不是驗收那天的考卷,是動工之前的照妖鏡;一句寫不成可檢查的話的需求,就是一句還沒問完的需求。

五句話貼上牆,總算可以動工了。有人開始拆 Ticket,手一順就拆成三張:前端、後端、金流——跟第三部一模一樣的拆法。

這次被攔下來了。完成條件都寫成一條線了,施工卻要切成三段各等各的?明天來講另一種切法:不要再 Backend 做完等 Frontend——先切一條細的。


上一篇
Day 25|User Story 不是魔法,真正重要的是 Conversation
下一篇
Day 27|Vertical Slice:不要再 Backend 做完等 Frontend
系列文
你以為自己很敏捷,其實連瀑布都沒做好——30 天從錯誤承諾、大神救火,到沒有大神也跑得動的開發方法27
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言