作者 | 李響
故事卡應盡量簡練,而非事無巨細應寫都寫;同時,應盡量完整、準確,而非缺少細節、模棱兩可。
這是我的基礎觀點,我的考慮如下:
- 簡練意味著讀者獲取的信息是經過提煉的,讀者閱讀起來是更高效的。
- 簡練意味著 BA 寫卡可以更高效,可以投入更多精力在其他更具挑戰的工作內容上。
- 完整、準確意味著故事卡是經過討論并達成一致的。
- 完整、準確意味著故事卡是有著清晰驗收標準的。
- 完整、準確意味著故事卡是便于追溯、便于傳遞的。
- ……
基于以上觀點再分類別展開聊下。
關于對頁面交互的描述
上圖展示了一個添加新賬號功能的 UI 設計。一種對該功能需求的描述可能是:
- 用戶通過主菜單進入“權限管理”模塊,選擇“賬號管理” Tab 頁,可以看到“新增賬號”按鈕。
- 點擊“新增賬號”按鈕,系統彈出新增賬號窗口(可能還會寫一句“背景置灰”)。
- 用戶可在窗口中填寫姓名、登錄郵箱……
- 若用戶未填寫必填字段,則點擊“確認”時給出錯誤提醒“請完成所有必填字段的填寫!”
- 點擊“確認”按鈕后彈出二次確認窗口,二次確認信息為“確認創建該賬號?賬號一旦創建成功即會郵件通知對應用戶”。用戶再次選擇“確認”則系統創建賬號,若用戶選擇“取消”則返回填寫賬號窗口。
這些文字描述沒有任何錯誤,應該還符合不少 Dev 同學或 QA 同學的胃口,但在我看來過于臃腫。嘗試思考簡化哪些信息不會影響 Dev 編碼和各角色理解業務:
(1) 詳細的操作步驟描述是否必要?
通常是不必要的。一般情況下設計圖或簡單的溝通是很容易表達這些內容的,故事卡中簡單地表述主要路徑即可,詳細的描述反而約束了設計和實現,并且讓故事卡變得臃腫。
(2) 描述所有字段是否有必要?
通常是需要的,但應該是從業務角度描述,后文有詳細聊到。
(3) 詳細地描述用戶操作后的系統反饋是否有必要?
通常不是必要的,因為絕大多數的系統反饋是約定俗稱或顯而易見的。比如 popup 窗口下方的頁面是被置灰的,popup 窗口上的“取消”按鈕點了后會關閉窗口,等等。那什么是“不通常”的情況呢?常見的是期望系統根據業務目標給出的反饋,比如我會注明“創建用戶成功后頁面應跳轉回列表頁”,因為我知道管理員通常會批量創建多個用戶,這樣效率更高。
(4) 二次確認功能中的文案是否有必要詳細描述呢?
很多時候是需要的,因為這些文案通常是想表達特定的業務含義的,用完美的文案將這層業務含義表達出來是 BA 的職責。那反過來的情況呢?比如一些常規的刪除操作的確認文案就不需要一一描述,可以與團隊約定好所有的刪除操作都需要二次確認,所有的二次確認文案都是“確認刪除該xx?刪除后不可恢復”,如有特殊情況再單獨表述。
那么對于上面的需求,我的描述會是這樣的:
權限管理員可創建新的用戶:
(1) 路徑:后臺管理端 - 權限管理 - 賬號管理 - “新增賬號” button
(2) 新增賬號所需字段
- 姓名…
- 登錄郵箱…
- ……
(3) 確認創建賬號需二次確認,文案“確認創建該賬號?賬號一旦創建成功即會郵件通知對應用戶”
簡單總結一下,在我的觀點中,故事卡通常不應對頁面交互做過多描述,這樣可能會約束設計和實現,還容易讓故事卡失去業務焦點。但若某個期望的交互具有獨特性或交互本身就是重要的驗收點,那么將他們簡練、準確地表述出來也是必要的。
關于對業務邏輯的描述
這里的業務邏輯可以狹義地理解為功能需求中的規律或規則,是我認為“如果有則必須體現在故事卡”的內容。我的理由如下:
- 它們通常是適配特定業務場景的,不是可以通過普遍認知推導出來的。
- 它們通常是核心的,直接決定著需求是否能達到預期收益。
- 它們通常是復雜的、難以記憶的。
所以我們可以直接討論下如何簡潔、準確地描述這些規則。
曾經處理過一個關于預約送貨的需求。背景是客戶采購“我們”的商品,物流承運商負責將貨物運送到客戶倉庫,但客戶倉庫常出現沒有可用倉位而導致承運商送貨到庫卻又無法卸貨入庫的情況。解決方案是客戶側開發預約留庫位功能并提供接口,我們調用該接口,告訴客戶方系統預計送貨信息,客戶系統對應預留倉位并反饋期望送貨時間,承運商確認后按該時間送貨。
這個業務場景的特點在于每個節點都有多種不確定性,由此為后續流程帶來不同的影響。在業務已經梳理清晰的前提下,這其實就是一個如何表達結構化信息的問題。
首先試下 Given When Then 的表達方式:
AC01 預約日期在窗口范圍內
When 客戶系統返回了“在預約窗口范圍內”的預約日期
Then 郵件通知承運商確認,變更預約單狀態為“待承運商確認”
AC02 預約日期在窗口范圍外
When 客戶系統返回了“不在預約窗口范圍內”的預約日期,且未人工確認
Then 郵件通知銷售負責人協調處理,變更預約單狀態為“待銷售確認”
AC03 預約日期已人工確認
WHEN 客戶系統返回了“不在預約窗口范圍內”但被標記為“已人工確認”的預約日期
Then 預約成功,變更預約單狀態為“預約完成”,郵件通知承運商按預約日期送貨
……
看起來能把每個細節表達清楚,但可讀性比較差,讀者可能需要額外的 effort 才能理清各場景間的邏輯關系。
然后嘗試下 “BA 式” 的偽代碼:
「
If 約定時限內獲取到了客戶系統反饋的預約日期
{
if 日期在預約窗口范圍內
郵件通知承運商確認,變更預約單狀態為“待承運商確認”;
else if 日期已人工確認
預約成功,變更預約單狀態為“預約完成”
else
郵件通知銷售負責人協調處理,變更預約單狀態為“待銷售確認”
}
else…
」
邏輯關系表述清楚了,但閱讀大段滿載邏輯的文字的體驗仍然不好,似乎可以再簡潔點。
最終我將這些規則用狀態轉換圖描述出來,然后與 Dev 和 QA 同學溝通是否可以用這張圖當做驗收條件。在與他們講解了這個圖后,大家認為只要對圖中各節點的業務意義達成一致并約定好 Scope(而這些是比較容易的),這樣的表述是更清晰、更友好的,于是我們愉快地接受了這種方式。
簡單總結一下,在我看來,對業務邏輯的表述是寫故事卡的重點和難點,BA 應該結合項目和需求特征選擇最佳表達形式,不用拘泥于固定的格式,其中圖表經常是不錯的選擇。關于圖表的使用有以下 tips 供參考:
- 復雜條件組合產生不同系統行為 (比如積分判定規則)> 判定表、判定樹或事件 - 響應表
- 復雜狀態規則(比如訂單狀態規則)> 狀態流轉圖或狀態表
- 復雜業務流程 (比如采購流程)> 業務流程圖
- ……
另外,團隊需要就如何理解這些新的表達方式達成一致。
關于對列表和表單的描述
列表和表單是最常見和最基礎的需求,往往套用固定的模式就可以將其表述清楚。
列表類需求常見的幾要素:
- 功能權限:誰在什么條件下可以使用該表單
- 數據權限:數據范圍的控制通常體現在列表上,比如用戶僅可見owner 是他自己的訂單記錄。
- 排序規則:列表中的記錄通常需要按一定的規則進行排序以便查看
- 分頁規則:如果某些列表中可以預見地記錄不會太多,那么不一定需要分頁,Dev 可以更簡單地處理這樣的列表。
- 字段清單:對列表中所有字段的描述。UX 的設計圖中會有這部分內容的體現,但經驗看來設計圖中不容易也不需要很及時地反饋字段的變化,在某些條件下設計圖也無法體現所有字段。
- 字段屬性:字段對應的業務含義,告訴讀者這個字段的值從何而來,如果某字段有特殊規則也可以在這里體現。比如【持續時長】字段是為了方便用戶查看,實際不對應數據庫字段,那這里就可以描述它的取值規則為“【當前時間】 - 【開始時間】,向上取整天”;再比如【門店名稱】通常較長但又很重要,我會描述“鼠標hover 在【門店名稱】時可查看其完整信息”。
一個有關列表的驗收條件參考如下:
AC01 查看發貨單列表:
(1) 路徑:主菜單 > 發貨單列表
(2) 功能權限:權限管理中新增“查看發貨單”權限,僅具有該權限的用戶可見“發貨單列表”菜單并訪問列表數據
(3) 數據權限:承運商用戶僅可查看他負責的發貨單,銷售用戶僅可查看他負責的客戶的發貨單,其他角色可見所有發貨單
(4) 排序規則:按發貨單創建時間倒序排列
(5) 分頁規則:15個/頁
(6) 字段詳情及順序
- 【發貨單創建時間】系統接收到承運商 TMS 系統推送的發貨單的時間,精確到分鐘
- 【發貨單號】承運商 TMS 系統的發貨單號
- 【門店訂單號】發貨單對應門店訂單的編號
- 【門店名稱】發貨單對應的收貨門店名稱,鼠標 hover 可查看完整名稱
- ……
關于表單類功能需求
表單通常是用于創建記錄、更新記錄、查看記錄的詳細信息,相比列表類需求對字段屬性的描述有以下幾點需要注意:
- 是否必須。
- 數據類型:比如對于時間類型字段,前端同學會處理為日期&時間選擇器。
- 校驗規則:比如對用戶名格式或對密碼復雜度的校驗。
- 若是pick list,那么選項是什么:選項可能是一些枚舉值,也可能是自另外的一個業務實體(比如為訂單選擇客戶),需要詳細說明。
- 字符長度:從業務角度給出字段長度建議。
所以某個表單的描述可能是這樣的:
(1) ……
(2) 字段詳情及順序
- 【姓名】必填,50字符
- 【出生年月】必填,日期類型
- 【省份】必填,單選,從基礎數據 region 表中取值
- 【城市】必填,單選,從基礎數據 region 表中取值,與【省份】聯動
- 【家庭成員數量】必填,正整數
- 【聯系郵箱】非必填,100字符,校驗為郵箱格式
- ……
這里面也有幾個可以探討的問題:
(1) 對于【聯系人郵箱】字段,通常會有對于郵箱格式的校驗。那么 BA 在故事卡里是否需要詳細描述校驗規則?
我的建議是沒必要。因為郵箱的格式校驗是一個有著“普遍認同”的規則,并不具備獨特的業務價值,不該因為 BA 的表述不同而不同。所以,這種問題可以交給 Dev 同學。
(2) 是否需要以及如何描述字符長度/數值范圍?
我的建議是可以描述。以字符長度為例,大多數字段其實是比較容易推斷出字符長度的,比如“訂單狀態”,10個字符足矣,Dev 和 BA 從各自視角判斷通常也偏差不大。那既然如此,BA 就順手寫出來吧,更何況存在某些字段在特定業務場景下有特殊要求的可能。
可能還有其他問題可以進一步討論,但總而言之,對于列表和表單類需求通常可以復用一套模板,再結合業務場景調整就可以搞定。
關于對接口的描述
個人最喜歡的就是接口類的故事卡了,無他,但簡單爾。
對于接口類需求,我通常做法是:
- BA 定義好接口業務上的數據結構、業務主鍵
- 與 Dev 線下討論達成一致
- Dev 補充技術細節形成接口文檔
- 把接口文檔附在故事卡里,補充業務場景、調用頻率(對于主動拉取數據類接口)、錯誤處理機制(比如提交訂單失敗后應重試還是立即報錯)、接口獲取/提供的信息的特殊處理(比如外系統給到的訂單我們要按照自己的規則生成新的訂單編號)等必要信息。
最后,對用戶故事業務價值的描述和故事卡的拆分也簡單分享下我的理解
我非常贊同每個故事卡都應該產生業務價值,并且我們應當將這個價值顯式地表達出來。而實踐下來,我發現一段“freestyle” 式的描述常常比“作為一個 <角色> , 我想要 <功能> , 以便于 <業務價值> ”這樣的表述方式更容易上手。
比如,某個需求是從主數據系統定時獲取最新的產品主數據,那么我會用這樣的一段文字來描述:
Summary:當前條件下,系統中的產品數據來自于每月客戶側產品經理給到的Excel 文件更新。客戶自主研發的主數據平臺已與上個月正式上線,并對外提供了數據分發接口,我們可以通過它提供的產品主數據接口每天獲取產品主數據的更新,以解決手工更新帶來的更新不及時、手工處理出錯等問題。
基于這種更自然的表達方式,我可以輕松地描述更多有價值的信息。
最后是我對 INVEST 原則(好的用戶故事的編寫應滿足的幾個原則)的一些理解:
- 獨立性(Independent) :應盡量避免故事間的強依賴,但若必須有強依賴,那么這些卡片應該可以在同一個迭代中完成。非獨立的故事會造成估算、排優先級和制定技術方案的難度。避免強依賴的方法可以有合并故事卡、換個維度拆分故事等,實在不行也不用強求,按依賴排好優先級即可。
- 可討論的(Negotiable):實現方案是可討論的,但業務目標應是明確的;討論是必要的,對方案達成一致更不可缺少;可討論不是BA 不去提前思考具體解決方案的借口,更不是卡片中驗收標準不明確的說辭。
- 有價值(Valuable):我想不出我們去做一個沒有價值的需求的理由…… 姑且把這一條理解為在寫下這張卡片時我們應該已充分了解它能解決的問題或帶來的收益,并且所有角色已經對此達成一致。
- 可以估算(Estimable):估算通常是為了排期,為了可以估算故事的規模應該足夠小,團隊對故事應該有充分的了解,并可以就故事內容對技術實現方案基本達成一致。
- 足夠小(Small):更小的故事有助于更準確的工作量評估或多人并行工作,可以讓故事卡在卡墻上更快流動起來,但也不必過分追求小故事,不少情況下 Dev 一次代碼提交同時處理兩個關聯需求要比先后處理這兩個需求要更簡單、高效,如果 Dev 經常說“這幾張卡我一起開了吧”或“關了吧”時,BA 可以請教一下他的想法,也許能發現值得改進的地方。
- 可測試(Testable):故事卡中描述的輸入和輸出是明確的、可度量的。
文章的最最后,再總結下我的觀點
- 我認同故事卡里非常詳細的描述可以帶來價值,但我也相信“簡練的表述 + 充分的溝通”可以更高效、更靈活。
- 我認同故事卡不是契約或合同,但我也相信完整、準確的表述可以顯著降低各角色間的溝通成本。
- 我認同可工作的軟件高于詳盡的需求文檔,但我也相信高質量的需求文檔可以帶來很多收益。
- 我認同最佳實踐和個人經驗(包括本文以上所有內容)的參考價值,但我更相信因地制宜、團隊共建的實踐才是最好的選擇。