什么是User Story
其實我覺得要對User Story做一個定義還是挺難的。
曾經的我以為,所謂User Story是User來講述的Story。
你看啊,User Story的編寫范式:
As a role, I want to do something or a piece of functionality, so that I can achieve some business value or statement of intent.
但是,隨著真正的實踐,我發現,User總是一個缺席的定義者。
我們指望User來定義User Story,而大部分情況下是由我們這群BA來定義的。
我曾經和一名敏捷教練討論,我們BA總是在臆想用戶的需要而寫User Story,這樣有意義嗎?
這名來自美國的副總裁回答我說,至少你們從用戶的角度來思考了,不是嗎?
不過,并沒有解答我的疑問,我也相信有很多人和我有同樣的問題:
User Story到底是從哪里來的?誰來寫?
也有很多人認為需求提出方應該來寫User Story,至少也應該來確認User Story是否恰當。
但實際情況是,很多時候我們真的只能靠想象,充分利用我們的“同理心”來想象。
我翻了一下BABOK中對于User Story的定義:
A user story represents a small, concise statement of functionality or quality needed to deliver value to a specific stakeholder.
——《BABOK 3.0》
這樣看來,User Story只是用來描述可以帶給User的價值的功能或質量需求,而非必須由User提供。
后面這段描述更加明確的指出了這點:
With a focus on stakeholder value, user stories invite exploration of the requirements by promoting additional conversations with stakeholders and grouping functional requirements for delivery.
——《BABOK 3.0》
這里,我們暫停一下,敲個黑板:價值。
User Story是強調給用戶帶來價值的。
OK,我們繼續。
廣為人知的拆分原則
User Story寫起來并不復雜,但是從敏捷的小步快走的角度出發,大部分的User Story是需要進行拆分的。
而各種敏捷著作中都有寫明 User Story拆分的INVEST原則:
Independent:獨立性
User Story必須高內聚,也就是擁有獨立性,不依賴于其他User Story的實現而實現。
如果你將一個User Story拆成前臺和后臺,那肯定不符合這個原則,因為這兩個Story的依賴性非常高。
Negotiable:可協商
User Story并不應該是一個人的一言堂。
之前有個小伙伴問我,是不是應該由BA來寫User Story。
我說,BA提供的是初稿,最終稿需要讓團隊所有相關人員達成一致。
Valuable:有價值
再次敲黑板,價值!
價值是User Story的關鍵所在,這個Story如果對用戶是沒有價值的,那就需要重新拆分或者重寫。
Estimable:可評估
在之前的Scrum文中,其實我提到了關于User Story的Point評估問題。
我們必須保證User Story的可評估,因為User Story是所有實現的基礎,我們需要根據評估的結果進行計劃、追蹤和回顧。
Small:足夠小
這個原則也決定了User Story要拆得足夠小,至于要拆多小,這個我個人覺得應該由團隊協商一致,至少也應該是在一個Sprint可以完成的程度。
我在之前的團隊里,當評估的點數大于3的時候,我們就一定要拆。
因為根據我們以往的經驗,5點及以上的User Story會導致我們的Sprint失敗,非常可能做不完或者測不完。
而拆分的過程也是一個再次思考和討論的過程,大家很有可能會發現之前被隱藏和遺漏的地方。
Testable:可測試
為用戶帶來價值的User Story必須是可以測試的。
請反復讀一下我上面這句話。
之所以稱以上原則為“廣為人知”是因為大家都知道拆User Story的時候要遵循這些原則,但是依舊不知道要怎么拆。
怎么拆都怪怪的?
還記得我上面敲黑板的兩個字嗎?
價值
所有User Story的拆分都要以價值為導向,在拆完后也需要通過“這個小的User Story有給用戶帶來業務價值嗎?”來校驗是否拆的合適。
這么說可能有點抽象。
我來舉個例子。
有這么個圖書館借閱系統的User Story:
作為一個用戶,我希望可以找到滿足條件的書籍信息,以便我可以在書架上找到它。
這個User Story有點大,好吧,不是有點大,是非常大。
如果你拿這個User Story去和大家討論,會面臨以下問題的解答:
- 這個用戶是注冊用戶,還是訪問用戶?
- 不同類型的用戶操作是一樣的嗎?
- 所謂的“滿足條件”指的是哪些條件?書名?作者?ISBN……
- 要展示的書籍信息包括什么?書名?索書號?館藏狀態?
……
于是大家討論了下,決定要拆。
這個User Story給你,你怎么拆?
以下是一種拆法,拆成兩個User Story:
第一個:建立圖書信息表,里面包括書籍的各種屬性。
第二個:按照原型,畫三個前臺界面,包括:搜索界面和搜索結果界面,以及圖書信息展示界面。
還嫌大?
那我就把第二個拆成三個,每個界面一個User Story,夠小了吧?
有沒有覺得哪里不對勁?
有人說,因為沒有按照User Story的格式來寫,沒有寫:
作為一個用戶,我希望可以查看搜索界面,這樣我就可以開始準備搜索了。
更奇怪了,是吧?
來,想一下,這些被拆出來的Story對用戶來說有業務價值嗎?
你提供一個前臺頁面給用戶,不能搜索,只能看,是準備打印出來掛到美術館里面“供人瞻仰”去嗎?
那么應該怎么拆呢?
我這里提供一個思路,大家可以揣摩一下。
大的User Story:
作為一個用戶,我希望可以找到滿足條件的書籍信息,以便我可以在書架上找到它。
第一個 User Story:
作為一個用戶,我希望可以通過圖書名稱找到圖書的書名、作者、館藏狀態以及索書號信息,以便我可以在書架上找到它。
第二個 User Story:
作為一個用戶,我希望可以通過圖書作者找到圖書的書名、作者、館藏狀態以及索書號信息,以便我可以在書架上找到它。
或者這么拆:
大的User Story:
作為一個用戶,我希望可以找到滿足條件的書籍信息,以便我可以在書架上找到它。
第一個 User Story:
作為一個用戶,我希望可以通過圖書名稱找到圖書的書名以及索書號信息,以便我可以在書架上找到它。
第二個 User Story:
作為一個用戶,我希望可以通過圖書作者找到圖書的書名、作者、館藏狀態以及索書號信息,以便我可以在書架上找到它。
有感覺到什么嗎?
嗯,這樣就萬事大吉了嘛?
我只能說,圖樣圖森破……
因為這里還有一個延伸的問題,就是程序猿GG看到這樣的User Story拆分,很想打人。
為什么?
因為在代碼實現的時候,其實在做第一個User Story的時候,可以“順手”把第二個User Story的邏輯實現了。
而如果不順手實現,那么意味著在做第二個User Story的時候會需要改才交付完成的第一個User Story的代碼。
就好像我們裝修房子。
之前的拆分方法是:水電進場開工、瓦工進場開工、木工進場開工、漆工進場開工、家具及軟裝進場。
而我后面的兩種拆分方法是:先把客廳的水電、地磚、墻面、家具軟裝都搞定后,再來依照這個順序搞一遍衛生間,再搞一遍臥室……
但是,看出差別了嘛?
前面的拆分方法一個工種干完,下一個接著干,只有當所有的都干完了,房子才能交付。
而后面的拆分方法至少保證第一個User Story可以交付一個完整的客廳給用戶,這對用戶來說是有價值的。
這也是敏捷的奧義所在。
但是,工人們肯定不樂意了,我水管先鋪一段到客廳的,后面我還要把鋪到客廳的一部分拆了再鋪到衛生間去……
哈,也從另外一面說明了敏捷方法明顯不適合工程裝修。
那么你要怎么說服大家接受User Story的價值導向的拆分方式呢?
關鍵在于,敏捷的另外一項重要工作:重構。
敏捷的開發過程其實很強調重構、自動構建等等。
所以,這也是為什么我一直覺得敏捷的框架和流程是一個完整的體系。
你不能拋開重構談User Story拆分,你也不能無視價值來寫User Story。
我大概花了兩三年的時間才摸索出來寫和拆User Story的感覺,當然這和業務熟悉程度也有一定的關系。
我想要說的是,想要拆好User Story是需要自己不斷的去摸索的過程,沒有辦法說我今天看了一篇文章或者聽了一堂課,我就能把User Story寫好、拆好了。
重點是要親自動手去拆,去寫,去試錯。
說了這么多,你在拆User Story的時候遇到了什么問題?
這篇文可以解答你的問題嗎?
歡迎你留言分享和討論關于User Story的問題。
也歡迎你提出你想知道的其他話題,我們可以一起討論。