1. 用例,用戶故事和特性的區別
需求階段是軟體工程中的一個重要階段,裡面涉及到需求收集分析,需求管理,需求開發,系統工程,易用性和交互設計,界面,業務領域知識,非功能性需求等多方面的內容。在面向對象的需求分析中我們通常採用用例分析的方法進行,在RUP核心三要素中第一位的就是用例驅動。 在《Use Case Modeling》一書中的定義是,用例代表了系統為其用角(Actors)所做的有價值的事情。用例不是功能(functions),也不是特性(features),它們不能被分解。每個用例都有一個名字和一段簡述。用例的詳細描述本質上是一些敘述(stories),說明了用戶如何使用系統來完成他們認為重要的事情,以及系統做了些什麼來滿足這些需要。 張洵對用例的定義是一種粒度剛剛好,反映了用戶的真實目的(目標),並記錄了為達到此目的(目標),用戶與系統或多個干係者之間如何開展協作,從事了哪些動態交互行為的軟體需求(表現形式)。 首先用例是描述功能性需求,而在描述過程中所涉及到的三要素就是人(Actor)和系統邊界,交互和動態行為。在需求分析中我們另外強調了輸入輸出,而在用例中對輸入輸出的描述是融入在基本流和擴展流的描述中。在敏捷方法中我們一般採用用戶故事卡(User Story Card),用戶故事卡對交互過程的描述可能並不會很詳細,但是更加強調了用戶驅動,強調了用戶場景,而這也是用例偏弱的地方。我們做任何需求都必須要清楚的知道是什麼樣的用戶和業務場景下驅動出了該需求。
2. 用戶故事(User Story)相關術語介紹
工作中遇到很多同事問到用戶故事的相關概念,而且基本是每新來一個同事就要解釋一遍,這里做個總結,希望以後不要再做這個重復性的工作了。😹
INVEST是用戶故事的書寫標准,具體每個字母的含義如下:
一個用戶故事對於另一個用戶故事應該是盡可能獨立的。為什麼呢?因為傳統的需求描述方式(功能模塊、用例等等)由於個體較大,彼此之間依賴較多,導致輸入到開發階段時開發工程師不太容易計劃他們的工作,從而導致的開發延期的現象就變成大家習以為常了。而獨立性較好的故事能夠獨立交付,從這一點,用戶故事就充分的考慮到了需求與開發的敏捷化連接問題。
那要如何才能做到用戶故事之間的獨立性呢?通常,可以通過組合用戶故事或者分割用戶故事來減少依賴性。
大家對所有之前達成的一致在新的變化發生情況下,協商後達成新的一致,從而推動系統的研發進展。
上面是比較書面的解釋,我的理解是這樣的:
用戶故事可協商的地方,在於驗收標准(AC),同樣一個手機號+驗證碼的注冊功能,我們既可以寫成如下的驗收標准(以下只是舉例,真實的驗收標准建議參照Given-When-Then的格式編寫):
如果按照這個驗收標准來做,一個注冊功能可能就要開發一周左右,但是早期我們為了快速進行後續的開發,可以暫時降低我們驗收標准:
這樣就能迅速完成注冊的功能,繼續後續的開發了。
這就是我理解的用戶故事的「可協商的」概念。
協商去掉的這些驗收標准,不是說以後都不做了,而是暫時為了完成整個MVP,就先犧牲掉了,這些細節還可以在後續的迭代里再加上。
每個故事必須對客戶具有價值(無論是用戶還是購買方)。一個讓用戶故事有價值的好方法是讓客戶來寫下它們。
書寫用戶故事的三段論:
作為(XX角色),我想(XX功能),從而(實現XX價值)
最後一句話,就是在強調價值的重要性。
開發者需要去估計一個用戶故事以便對故事進行規劃。但是讓開發者難以估計故事的問題來自:對於領域知識的缺乏(這種情況下需要更多的溝通),或者故事太大了(這時需要把故事切分成小些的)。
一個好的故事應該在工作量上短小,描述具有代表性,而且不超過3人天(或者3故事點)的工作量。超過這個范圍的用戶故事,將會在劃分范圍和估計時出現很多錯誤。
一個用戶故事是可測試的並用來確認完成,記住,我們不開發不能測試的故事。如果你不能測試那麼你永遠不知道你什麼時候是完成了。
小結
一個編寫良好的用戶故事是敏捷開發的基礎。它們應該相互獨立,詳情應該便於開發者和用戶進行溝通,應該對用戶有價值,應該對於開發者來說盡可能的清晰以便進行估計,應該短小,通過預定義測試用例的使用確保它是可以測試的。
3C是收集用戶故事的有效手段,具體每個C的含義如下:
用卡片(Card)來簡要描述故事。
與Proct Owner(或客戶)交談(Conversation)來明確細節。
驗收評審,確認(Confirmation)被正確完成。
DEEP原則是用來梳理Proct Backlog的,改概念最早在 Mike Cohn 的《Succeeding with Agile》一書中提到。
接下來的1~2個Sprint中要完成的用戶故事,需要足夠的詳細。而不著急開發的,則不必太詳細。
Proct Backlog中的需求都要是經過估算的,只不過靠後(優先順序低)的PBI沒有充分理解(也不必),因此其估算也不如靠前(優先順序高)的PBI估算精確。
Proct Backlog不是靜止的。隨著了解的深入,Proct Backlog中的用戶故事會增加、減少、刪除、拆分或重新排優先順序。
Proct Backlog應該根據由上至下按照條目的價值從高到低排序。團隊應根據優先順序進行開發,從而使正在開發的產品或系統價值實現最大化。
規模化敏捷框架 SAFe (Scaled Agile Framework)提出了一種定量計演算法來評估需求的優先順序,稱為WSJF(Weighted Shortest Job First: 加權最短作業優先)。
計算公式如下:
其中分母的工作規模部分大家比較熟悉,即估算的需求規模(故事點方法、理想時間方法等)。
分母部分的延期成本包括三個因子:
指的是對客戶或商業的相對價值,比如:
用戶更喜歡哪個?
對盈收有什麼影響?
不做會產生什麼潛在的負面影響?
指的是給用戶的商業價值隨著時間的推進如何變化。比如:
是否是固定交付日期類型的需求?
用戶是否會願意等待,還是會選擇其他產品?
在某個時間窗口不上線的話,是否會影響用戶的滿意度?
指的是除了上面的第1個和第2因子需要考慮因素之外,這個需求還能為業務帶來哪些價值, 比如:
是否降低產品以後交付某些必要特性的風險?
是否會學到我們不知道的知識或信息?
是否會帶來新的商業機會?
這樣拆解後,WSJF的公式細化為:
如何操作呢?將所有特性列成表,如下:
對這個表中WSJF公式中的每個因子,採用與用戶故事的故事點相對估算類似的方法做估算。比如,對於工作規模這一項,選擇一個工作規模最小的特性作為基準,它的工作規模設為1( 注意:WSJF公式中的每一項,都要選中一個特性作為相對估點的1 ),其他特性的工作規模與之相對比, 採用 近似斐波那契數列 1, 2,3, 5, 8,13, 20…為單位。如果特性A是基準特性的3倍,那麼特性A的工作規模就是3。
為WSJF公式分子的其他因子做同樣的相對估演算法,即找到一個因子最小的基準特性,然後其他特性與之相比較,從而得到相應因子的估算數值。
就每一個特性,將WSJF的每個因子做相對估算後,就可以計算出每個特性的WSJF,這樣你就得到了量化的需求排序。
常見疑惑:WSJF適用於所有需求的排序嗎?
不是的。在 SAFe 里,WSJF可以適用於大粒度的Epic和Feature級需求,不適用於小顆粒的用戶故事級需求,原因是用戶故事通常很小,分母的幾個因子不容易對比出差異。此外這種定量計演算法在團隊里應用過於沉重,因為需要對每個需求估算四個因子,不止是需求規模這一個因子,所有估算的耗時翻了四倍。
MoSCoW法則是用來排定用戶故事優先順序順序的一種定性方法。
具體這個縮寫的含義是什麼,具體怎麼用,可以參考這篇文章: 如何利用MoSCoW法則排定Sprint Backlog的優先順序
SMART是用來將用戶故事拆分為任務時的指導原則。
任務必須是具體的。
任務必須是可以衡量的。
任務必須是可以達成的。
任務與最終目標是要相關的。
任務必須具有明確的截止期限。
3. 用戶故事與敏捷方法
故事的好處
軟體開發是漸進明細的過程,充滿挑戰。軟體需求是被識別為最常見的痛苦根源。如何定義需求,冗長的文檔已經不被閱讀者接受,簡單、精準、一目瞭然的格式一致的用戶故事越來越被接受。當掌握剛剛足夠的信息就繼續前行,按需及時開展,通過交談獲取所需要的細節。從用戶角度出發描述功能,讓我們站在最終用戶立場考慮問題,避免開發者自行其是。
方便溝通和傳遞,只有一句話或者簡短描述就能知道用戶訴求,比任何長篇大論漂亮的需求文檔好太多。更多的細節在交談中獲取,強調頻繁的溝通和反饋。
用戶故事的組成
用戶故事描述了對用戶,系統或者軟體購買方有價值的功能。一般由以下三個方面組成:
1,一份書面的故事描述,用來做計劃和提示
2,有關故事的對話,用於具體話的故事細節
3,測試場景或者舉例,用於表達故事細節且可用於確定故事何時完成。
一般故事寫在卡片上,正面描述,反面是驗收測試場景,另外可以在空白處加上優先順序,以及談話中討論的細節提醒。
如果一個故事太大(史詩故事Epic),那麼需要再細分為更小的故事,直到每一個故事能覆蓋到每一個細節,每一個細節之間都不能有重復,避免沖突和減少依賴。
使用故事的過程
過去是瀑布,強調文檔編寫完再設計,所有細節設計完成後進入開發,開發完成後進入測試。如果使用故事則玩不通,因為故事強調溝通,最需要的是客戶和用戶在項目中全程參與,需要在項目中隨時可以找到可溝通的人,得到正確和真實的反饋。
讓用戶編寫故事
軟體客戶和用戶應該在編寫用戶故事時承擔活躍的角色,客戶參與寫用戶故事有兩個好處,首先那個故事必須使用業務語言寫,而不是使用技術語言,這樣團隊可以排列故事優先順序;其次作為產品的構想者和使用者,用戶和客戶應該最清楚和適合描述產品的行為!
優秀的用戶故事准則
目標故事:了解使用軟體的目的,通過目標衍生故事。例如找工作是一個目標,那麼可以拆分為搜索工作,編寫簡歷,投遞簡歷,申請工作等……
切蛋糕方法:面臨一個大的故事,採用縱向切蛋糕的方法拆分更小的故事,每個故事都提供某種完整的end to end(閉環) 的功能。例如「求職者可以發布簡歷」這個故事拆分「求職者可以提交簡歷,簡歷包括名字,地址和教育背景這樣的基本信息;求職者可以提交簡歷,簡歷包括僱主想看到的所有信息。
在編寫故事時,更傾向編寫一整塊完整蛋糕那樣功能完整的故事。
編寫封閉的故事
一個封閉的故事是指隨著一個有意義的目標的實現而結束的故事,讓用戶覺得使用後能完成某個任務。而不是開放性,比如管理簡歷就是個開放性的故事;而保存簡歷,刪除簡歷,更改簡歷的信息,就是封閉式的故事。好處在於每個故事都是一個閉環,用戶會有一定程度成就感。
卡片約束
任何必須遵守而不需要直接實現的故事,設定為約束。如「系統必須要支持最大50個並發用戶的峰值」。約束卡片不需要估算,也不會被安排到迭代中,可以作為其他可能關聯故事實現時候的提醒。
不要過早的涉及用戶界面
項目早期應該對系統設計還沒有一個深入設計,很多需求都只是一個構想,如果過早的設計用戶界面,那麼會將用戶界面細節陷入故事。軟體設計是個漸進明細的過程,請不要違背這個過程。例如,如果項目剛開始就設計一個「用戶可以在搜索界面上從日期部件上選擇日期」,那麼其實對於開發人員來說是比較困難去開發的,因為在早期軟體可能還沒有設計搜索和日期相關的功能,盡量不要因為過早設計頁面左右了真實需求。 軟體只有在越來越完整的時候,並且從全新的功能轉向修改或擴展現有功能的時候。
在故事中包括用戶角色
如果項目已經識別了角色,那麼請在故事中使用已經識別的角色。這樣可以讓用戶在開發人員腦子里保持著最重要的位置。例如不要寫「用戶可以發布簡歷」,應該描述為「求職者可以發布簡歷」。這樣開發者會聯想到實際的,真切的用戶,開發出滿足用戶需求的軟體。
只為一個用戶編寫
當故事只為單一用戶編寫時,故事的可讀性通常是最強的。如「求職者可以刪除簡歷」,應該描述成「求職者可以刪除他自己的簡歷」。從單個用戶角度思考問題,會讓故事更清晰。
故事發布計劃
Must have 必須有(基本功能)
Should have 應該有(很重要但是短期內有可替代解決方法的功能)如果項目時間沒有約束,應該有的功能應該是強制性的
Could have 可以有(如果沒時間,可以在發布中不考慮的功能)
Won』t have this time 這次不會有(客戶期望有,但是承認需要在後續發布中實現的功能)
排列優先順序
用戶對故事進行優先順序排序,一般會從廣泛性和重要性開來判斷。
如果用戶的優先順序和開發人員實現的順序不一樣時,應該客戶說了算。在確定優先順序時,應該先對故事進行估算,這樣用戶可能重新調整優先順序,根據估算大小,評估發布順序讓價值最大化。
迭代計劃
講解故事,澄清問題,優先順序排序,任務拆分,任務認領,評估任務是否能完成。
拆分任務
1 實現故事的開發人員一般不是一個人
2 故事拆分為開發人員的待辦事項(to do list)時團隊透明,團隊集體智慧有助於不容易遺忘
3 拆分任務的同時也是一個即時設計短脈沖的過程,這個過程類似瀑布過程的前期設計階段
4 團隊成員自願認領和執行任務
5 團隊圍繞共同目標執行迭代,在迭代後期如果有人任務無法完成,團隊其他人應用於承擔,避免有人任務完成,還有人的任務列表還有待處理的情況。。
用戶故事的優勢
強調口頭溝通,人人都可以理解用戶故事,用戶故事大小適合做計劃和迭代開發。
用戶故事鼓勵延遲細節,並根據溝通適應隨機應變。鼓勵參與性設計和傳播陰性知識。此部分難以理解,目前我們仍然使用prd記錄和描述用戶需求,盡可能記錄清楚用戶訴求自己可能場景和用例。此處和書上描述避免使用過詳細的記錄相悖論。我們因為部門牆的存在,用戶可能沒辦法和研發團隊頻繁交流,且反饋環拉的很長。我們產品經理就處於與用戶溝通和設計產品的角色,所以大家還是希望產品能將溝通記錄和結果記錄清晰。
用戶故事促使我們重視口頭交流,提供迅速的反饋周期,促使對需求的理解。用戶故事范圍比用戶用例(IEEE830 定義的軟體需求包括用戶用例和場景)場景
4. 我們常說的用戶故事是什麼
1,用戶故事的概念
概念這種東西我喜歡說文解字的方式去理解和闡述。用戶故事=用戶+故事=人+故+事,那就是一個人因為什麼原因要做什麼事,提煉出來三要素就是who、why、what。從需求角度描述就是一個用來確認用戶和用戶需求的簡短描述。
2,用戶故事的三要素
用戶故事在軟體開發過程中被作為描述需求的一種表達形式。為了規范用戶故事的表達,便於溝通,用戶故事通常的表達格式為:作為一個<用戶角色>, 我想要<完成活動>, 以便於<實現價值>。
一個完整的用戶故事包含三個要素:
(1)角色(who):誰要使用這個
(2)活動(what):要完成什麼活動
(3)價值(value):為什麼要這么做,這么做能帶來什麼價值
3,3C原則
用戶故事的描述信息以傳統的手寫方式寫在紙質卡片上,所以Ron Jeffries(2001)對這三個方面稱為3C:卡片(Card)、對話(Conversation)和確認(Confirmation)。
(1)卡片(Card):用戶故事一般在小卡片上寫著故事的簡短描述,規則和完成標准。
卡片的正面書寫故事的描述,格式為:作為一個<角色>, 我想要<完成活動>, 以便於<實現價值>描述需求;卡片背面書寫完成用戶故事的規則和完成標准,格式為:Given…When…Then。
(2)交談(Conversation):用戶故事背後的細節來源於和客戶或者產品負責人的交流溝通。確保各方對故事的理解正確。
(3)確認(Confirmation):通過驗收測試確認用戶故事被正確完成。
4,INVEST原則
好的用戶故事除了格式規范,要素完整外,還應該遵循INVEST原則:Idependent(獨立的);Negotiable(可協商的);Valuable(有價值的);Estimatable(可評估);Small(小的);Testable(可測試的)。
(1)Idependent(獨立的)
要盡可能的讓一個用戶故事獨立於其他的用戶故事。用戶故事間保持獨立性不僅便於排列和調整優先順序,使得發布和迭代計劃更容易制定,便於獨立地理解、跟蹤、實現、測試以及頻繁交付,也使得用戶故事的大小估算所涉及的范圍更清晰,從而估算偏差更小。
(2)Negotiable(可協商的)
一個用戶故事的內容要是可以協商的,用戶故事不是合同。一個用戶故事只是對用戶故事的一個簡短的描述,不包括太多的細節。具體的細節在溝通階段產出。一個用戶故事帶有了太多的細節,實際上限制了用戶、團隊的想法和溝通。
(3)Valuable(有價值的)
每個故事必須對客戶具有價值(無論是用戶、購買方還是公司內部角色)。用戶故事對於最終的用戶是有價值的,因此應該站在用戶的角度去編寫,描述的是一個一個的feature,而非一個一個的task。這個特點促進團隊的開發和測試成員由傳統的指令式工作方式向自驅動的價值導向工作方式轉變,使團隊中的每個人知道自己每天做的工作價值。
(4)Estimatable(可評估)
計劃會議裡面一個很重要的環節,那就是故事點的估計。實際上就是對要開發的User Story進行一個粗量級的估算,以便於團隊能夠知道這個user story的復雜度(工作量),重點放在當前迭代里能否按照該用戶故事的接收條件和團隊定義的DoD(完成標准)來完成這個用戶故事,如果不能完成,給出理由,由PO來決定是否拆分或者重新設計用戶故事。讓開發者難以估計故事的問題來自:對於領域知識的缺乏(這種情況下需要更多的溝通),或者故事太大了(這時需要把故事切分成小些的)
(5)Small(小的)
一個好的故事在工作量上要盡量短小,最好不要超過10個理想人/天的工作量,至少要確保的是在一個迭代中能夠完成。用戶故事越大,在安排計劃,工作量估算等方面的風險就會越大。
(6)Testable(可測試的)
一個用戶故事要是可以測試的,以便於確認它是可以完成的。如果一個用戶故事不能夠測試,那麼你就無法知道它什麼時候可以完成。一個不可測試的用戶故事例子:軟體應該是易於使用的。
5,三個准則
用戶故事在遵循了INVEST原則後,基本就是一個好的用戶故事了。再重點分析三個准則,幫助在產出用戶故事時更好地符合原則。三個准則是:一個用戶、完整價值、不依賴
(1)一個用戶
只包含一個用戶,因為多個用戶常常有細微的差別。一般是典型的用戶,常常有共同的某類需求。
(2)完整價值
完整地交付一個客戶價值。一個完整的用戶故事意味著這個故事完成後,用戶可以達成一個明確的、有意義的目標。
(3)不依賴
依賴性的三種常見類型是:重疊、順序和包含。總體上來說,故事之間功能點相互重疊是需要避免的;順序關系是現實存在,在多數情況下可以通過一些手段解決;包含關系對復雜系統是有幫助的,對排定發布和迭代計劃的影響需要注意。
1.重疊依賴
重疊依賴是帶來最多困擾的依賴形式,特別是多個用戶故事包含多個不同的重疊部分時,很難找到一組用戶故事可以代表該最小可行產品的功能集合,該集合應該包含且僅包含一次需要的功能。
解決方式:
將重疊部分單獨剝離出來做為獨立的用戶故事
合理拆分用戶故事,並且將重疊部分只保留在一個最有內聚性的用戶故事中
使用Scrum開發模式
2.順序依賴
順序依賴是指要使某用戶故事完成,另外的一個或多個用戶故事必須在它之前完成。順序依賴通常是無害的,而且有一些方式可以減輕這種依賴。從敏捷開發的角度,整個系統是從初始的最小可行產品逐步演化為強大的產品,後面的每一步是建立在前面的基礎之上的。但從另外的角度,不必要的順序依賴使得排列和調整優先順序變的比較困難,進而影響制定發布和迭代計劃,也使得用戶故事的大小估算更難以把握。
解決方式:
一個迭代內的用戶故事盡量做到沒有內在依賴。
保持迭代之間只有單向依賴,在時間上只有後面迭代的故事對前面迭代故事的單向依賴(前向依賴)。
剝離出核心依賴作為獨立的故事,不要把有依賴和無依賴的需求混在一個故事裡。
3.包含依賴
包含依賴是指在組織用戶故事時使用有層級的管理,比如常見的特性-故事兩級管理,一個特性包含多個用戶故事,這樣就構成了特性對其屬下故事的包含依賴。
解決方式:
用戶故事一級用來做迭代計劃,避免用特性一級做粗粒度迭代計劃,特性一級可以用來做發布計劃
特性一級同樣可以進行拆分,直至拆分到最小市場化特性的程度,並將其包含的用戶故事分別歸到新拆分出的特性中去
遵從最小可行產品的理念,一個特性分多個用戶故事多個迭代實現,每一個迭代可形成潛在可交付或者提供內部或外部反饋。