王春暉,金 芝,趙海燕,劉 璘,張 偉,崔牧原
1(北京大學 信息科學技術學院,北京 100871)
2(高可信軟件技術教育部重點實驗室(北京大學),北京 100871)
3(清華大學 軟件學院,北京 100084)
4(內蒙古師范大學 計算機科學技術學院,內蒙古 呼和浩特 010022)
軟件開發過程中,需求很難一次性完整獲得,而且也會頻繁發生變更.傳統方法試圖在開發前完成并確認整個需求文檔,但這樣開發出的軟件產品常常因不滿足用戶需要而使項目以失敗告終[1].敏捷方法注重領域用戶與開發團隊的頻繁交互,能夠快速響應需求變化,在較短的時間內開發出滿足用戶需求的軟件產品[2].但開發者如何能夠準確理解領域用戶需求并有效地維護和管理需求變更,仍然是困擾敏捷開發團隊的難題.
一方面,在敏捷方法中,用戶故事是領域用戶表達需求的最主要方式,該種方式只對意圖進行簡短說明[3],需要開發者與領域用戶進一步溝通,以形成系統功能說明.另一方面,在發布規劃時[3](規劃迭代開發選擇的用戶故事,確定項目時間表),需要根據領域用戶對特定功能特征的急切程度以及用戶故事間的關系排列用戶故事的優先級.目前,一般通過領域用戶與開發者之間的反復交流和討論,建立起用戶故事索引表,人工梳理故事間的關系[1-3].大型軟件開發一般會產生大量用戶故事,每天都出現大量的新增需求,比如百度公司每天新增需求卡片近6 700 個[4].用戶故事間的關系可能錯綜復雜,它們常常重復和不一致.建立起完整的故事關系,特別是建立新增的和已有的用戶故事間的關系非常困難.如果能有一種(半)自動化的手段幫助處理用戶故事文檔,進行需求抽取以及關聯關系挖掘,將有可能輔助實現高效的用戶故事管理.
為了降低敏捷團隊成員間溝通和理解的困難程度,領域用戶可以描述更多的系統行為,以方便開發者確定系統功能.行為驅動的敏捷方法[5,6]提出使用場景(scenario)更細粒度的描述用戶故事,表達用戶故事在不同狀況下的系統活動,便于在開發前進行需求驗證及測試.場景描述了用戶故事在特定上下文中的結果.這種描述方法以領域用戶所希望的系統行為出發,引導領域用戶提出需求.系統行為源于待開發軟件產品的業務結果,表明,為了達成業務結果應該如何去做.因而,容易被領域用戶接受.同時,在場景中關注目標系統的細粒度行為需求,更容易被開發者理解和實現.
一個軟件系統通常有很多用戶故事,需要一種有效的方式將這些用戶故事組織在一起,建立用戶故事之間的關系,形成對未來系統的整體需求[7,8].目前已有一些整合用戶故事的方法[9-11],它們通過建立用戶故事與需求模型之間的映射,實現從一組用戶故事到需求模型的轉換,包括從用戶故事到Use-Case 模型[12]、業務流模型[10]以及目標模型[11]等的轉換.也有方法借助自然語言分析技術自動地從用戶故事中提取概念模型,并檢查需求的完整性[9,13,14].但是由于自然語言描述本身的二義性及用戶故事描述的不規范,全自動的模型轉換非常困難.目前,大多數方法都僅提供模型編輯工具,輔助模型生成[9-12]等.
敏捷開發過程中,需求并不是事先定義好的,而是通過利益相關者之間的頻繁交互,隨著迭代開發過程逐步變得清晰[1-3,15,16].在每個迭代周期結束時,領域用戶根據對已實現功能的測試及評估結果提出需求變更申請,主要包括添加或刪除功能或修改已實現的功能.變更的功能(用戶故事)應該快速地融合到系統需求模型中,以實現模型的快速更新,還需要檢查更新的需求與前期版本需求是否存在沖突[17].目前,用戶故事管理的辦法主要是建立用戶故事列表和索引卡,人工分析用戶故事的變化[3]以及變更的成本和風險.有的研究通過分析多個連續版本的需求文檔來評估需求變更的風險[18,19],也有的研究提供輔助平臺,借助相關領域知識幫助管理需求演進[20].
本文提出一種敏捷需求工程場景下的人機協作式用戶故事理解和系統功能需求獲取方法.該方法提出帶場景的用戶故事表示,當領域用戶提交一組用戶故事后,可根據用戶故事元模型,借助用戶故事模板以及句法規則,采用自然語言分析技術,進行用戶故事的特征抽取和功能表達.提出基于用戶故事概念關系推理規則的用戶故事關系挖掘,識別用戶故事間的合作關系、執行依賴關系以及近義關系.經過領域用戶的確認,獲得用戶故事間的關系,生成系統功能場景.出現用戶故事更新請求時,可借助系統功能場景,交互式地更新系統需求.案例研究展示了方法的可行性.
本文第1 節介紹方法的整體框架.第2 節介紹用戶故事和系統功能場景的概念模型.第3 節介紹用戶故事場景抽取.第4 節介紹用戶故事關系挖掘及沖突檢查,以及系統功能場景的生成與更新.第5 節通過一個含有24 個用戶故事、57 個場景的在線購物系統實驗案例,驗證本文方法的可行性.第6 節介紹相關工作.最后是結語和展望.
人機協作的系統功能需求管理方法,主要包括用戶故事功能場景抽取、系統功能場景構建以及用戶故事場景更新3 部分工作,整體工作流程框架如圖1 所示.

Fig.1 The framework for elicitation and evolution of user stories with scenarios圖1 用戶故事場景抽取與迭代演進整體框架
用戶故事功能場景抽取以帶有場景的用戶故事為輸入,使用自然語言分析方法,抽取功能場景的結構化模型表示,得到功能場景表示.首先,借助用戶故事模板提取帶場景的用戶故事的字段信息,得到帶故事語義標簽的結構化文檔,稱為故事結構文檔.然后,應用抽取規則,從故事結構文檔中抽取功能場景表示,包括故事描述、場景以及功能特征屬性集3 個部分.其中,故事描述部分記錄了故事名字以及角色、意圖等.從故事結構文檔的對應存儲字段抽取.場景部分描述故事的意圖達成,表達為在具體的上下文(即用一組業務實體屬性的取值表示的狀態集)中,當某個事件發生時,意圖達成的結果(即新的狀態集).這樣,場景實際上就是從一個狀態集出發,經過事件,達到結果狀態集,這稱為一個狀態變遷.一個用戶故事的意圖是否達成,可能有多種情況.所以,一個用戶故事可能有多個場景.一個用戶故事中的所有場景組成一個狀態變遷集.應用狀態合并規則,合并狀態變遷集,生成狀態變遷圖.從狀態變遷集中提取反映意圖達成所需要的系統功能相關的業務實體屬性,得到功能特征屬性集.故事描述、功能特征屬性集以及狀態變遷圖組合在一起,形成一個用戶故事的功能場景表示.
系統功能場景構建以一組帶場景的用戶故事為輸入,通過功能場景的整合,形成系統用戶故事需求.首先,從用戶故事集中抽取用戶故事功能場景,得到具有故事描述、功能特征屬性集及狀態變遷圖的功能場景表示,稱為功能特征節點.這樣,用戶故事集就表達為一組功能特征節點.其次,通過和領域用戶交互確定用戶故事之間的關系,分為合作關系、執行依賴關系以及近義關系3 類,通過相應的推理規則計算用戶故事間關系的關聯強度,將存在較強關聯的用戶故事對作為候選關系集推薦給領域用戶.領域用戶確認后,得到用戶故事間的關系集.對存在近義關系的用戶故事要進行沖突檢查(語義冗余或不一致).在沒有沖突發生的情況下,用戶故事間的關系將功能特征節點連接起來,形成系統功能場景.
用戶故事場景更新以用戶提交的更新和當前版本的系統功能場景為輸入,根據不同的更新請求,交互式地進行需求的更新,得到系統功能場景的更新.更新操作包括添加新用戶故事、刪除和修改已有用戶故事.增加新用戶故事需要領域用戶提供一個帶場景的故事,通過執行用戶故事場景抽取創建新的功能特征節點,在當前版本的系統功能場景中尋找可能與它相關的片段,進行依賴關系識別,確定新用戶故事在當前版本系統功能場景中的位置及關聯關系,這個過程也需要領域用戶的參與.然后進行沖突檢查,如果沒有沖突,則插入新故事.刪除用戶故事首先需要領域用戶輸入要刪除用戶故事的關鍵信息,然后在當前版本系統功能場景中進行用戶故事檢索,以確定要刪除的故事及其關系.最后刪除該用戶故事并修正其他用戶故事之間的關系.修改已有用戶故事首先要在當前版本系統功能場景中檢索用戶故事定位要更新部分,然后修改用戶故事文檔,得到修改的用戶故事.最后,再將這個用戶故事作為新的故事文檔添加到系統功能場景中.
圖1 給出的方法整體框架,蘊含著以下3 個方面的問題.
(1)系統功能場景的表示.系統功能場景刻畫了帶場景的用戶故事的結構化表示以及用戶故事之間的關系.系統功能場景實際上是系統的功能模型,基于系統功能場景的用戶故事管理是一種模型驅動的管理,它直接制導了用戶故事功能抽取、整合和更新.第2 節將對此給予重點介紹.
(2)用戶故事場景抽取.這是指根據帶場景的用戶故事構造系統功能場景中的功能特征節點,具有故事描述、功能特征屬性集以及狀態變遷圖3 個屬性.它是生成系統功能場景和實現更新管理的基礎.本文借助自然語言分析技術和故事特征句法規則,從用戶故事文檔中構建功能特征節點.這方面的內容將在第3 節加以介紹.
(3)系統功能場景的生成與更新.建立用戶故事間的關系是生成和管理系統功能場景的關鍵.由于用戶故事都是獨立提交的,其中并沒有顯式表達和其他用戶故事的關系,如何輔助領域用戶快速識別用戶故事間的關聯,并檢查用戶故事之間的沖突,成為關鍵.第4 節將主要討論這一問題.
領域用戶采用用戶故事描述他們對軟件系統的需求.講述作為一個特定角色的使用者,需要什么功能,完成什么操作,帶來什么好處[3].為了對用戶故事進行細粒度的分析,提取其中的功能需求,可以進一步引入場景描述.即用戶故事包括至少一個場景,表達用戶故事發生的實例.另一方面,系統功能場景則站在未來軟件系統的角度表達系統應該具有的功能及完成的操作.本節通過ATM 機系統的案例介紹帶場景的用戶故事描述以及系統功能場景的概念模型.
帶場景的用戶故事包括故事描述及場景.故事描述包括故事名、角色、意圖以及收益.場景包括場景名、上下文、事件以及結果.一個用戶故事可以包括一個或多個場景.其描述模板及其概念元素層次關系如圖2所示.

Fig.2 The template and the hierarchical relation of elements in user-story description document圖2 帶場景的用戶故事描述模板及其概念元素層次關系
故事名一般以短句概括用戶故事的功能.角色表示誰將使用這個功能,意圖表示角色希望系統提供什么樣的功能,收益表達了系統實現該功能后的好處.場景描述了用戶故事在特定上下文中,發生某個事件而產生的結果.上下文和結果一般描述與功能相關的業務實體(屬性)的某種取值,體現了功能業務的狀態特性,用一個描述狀態(實體-屬性-值)的短句表達,分別用關鍵字Given 和Then 連接.當上下文或結果涉及多個狀態表達時,將每個狀態描述短句分開,并用and 連接.上下文和結果之間的切換是由于發生某個事件(如動作或條件達成),事件用關鍵詞When 連接.
表1 描述了持卡人在ATM 機上取現金的用戶故事.該用戶故事分3 個場景描述意圖是否達成:成功取款、卡余額不足不能取款和卡無效無法取款.取現金業務與賬號余額、卡是否驗證通過(是否是合法用戶)、取款金額以及ATM 機余額等實體屬性相關,稱為與用戶故事功能(意圖)相關的功能特征屬性集.這些功能特征屬性在每個場景中實例化(取值),表示這些功能特征屬性處于“上下文”狀態下(前置狀態),由于某個事件發生,功能特征屬性處于“結果”狀態(后置狀態).如scenario1 前置狀態中描述的短句含義是:在賬號的余額是balance,卡被驗證通過且ATM 機有足夠的現金.事件是“持卡人取現金cash”.后置狀態描述的短句含義是:ATM 吐出現金,系統提示取款成功,賬號余額會修改.

Table 1 The user story for card holder withdrawn money表1 “持卡人取現金”用戶故事描述文檔
為了讓開發者能夠充分理解用戶故事中每段描述的含義.建議在每個關鍵詞后面使用規范的句型,見表2.

Table 2 Recommended pattern for a sentence followed by a key word in a user story表2 用戶故事場景自然語言描述關鍵詞后面對應短句的推薦描述句型
系統功能場景是一個由功能特征節點和關系組成的圖.系統功能場景的概念模型如圖3 所示.

Fig.3 The conceptual model of system feature-scenario圖3 系統功能場景的概念模型
每個功能特征節點有3 部分信息:故事描述、功能特征屬性集以及狀態變遷圖.故事描述包括故事名、角色、意圖以及收益.功能特征屬性集是一個由實體-屬性組成的集合.狀態變遷圖是多個場景的狀態變遷組織在一起的圖結構,每個狀態變遷從一個狀態轉換到另一個狀態.其中,起始狀態是狀態圖的開始點,可以連接一個或多個組合狀態.組合狀態可以作為前置狀態或后置狀態,通過狀態變遷關聯起來.組合狀態中的每個原子狀態是功能特征屬性集中某個實體-屬性的實例(取某個值).
功能特征節點之間存在3 種關系:合作關系、執行依賴關系和近義關系.合作關系表達一組故事通過合作共同達成一個較大規模的故事.執行依賴關系表明一個故事的執行依賴于另一個故事的實現.近義關系表明故事可能具有相似的語義.合作關系和近義關系是雙向關系(互為合作關系或近義關系),一個功能特征節點可以沒有雙向關系或有多個雙向關系.執行依賴關系是有向關系(一個功能特征節點X是另一個功能特征節點Y的前驅,Y是X的后繼),一個功能特征節點可以不作為其他任何功能特征節點的前驅(后繼),也可以作為多個功能特征節點的前驅(后繼).
設實體、屬性、值、事件是系統的4 個基本數據集,分別表示為Entity、Attribute、Value、Event.實體具有名字及屬性,屬性包括名字及類型,事件描述動作或者某個條件(如系統所處狀態)的發生.值是滿足屬性類型的數據.對于圖3 所示概念模型中的元素,分別給出具體定義和形式化表示.
定義1.原子狀態S是一個三元組(entity,attribute,value),其中,entity∈Entity表示實體,attribute∈Attribute表示實體的屬性,value∈Value表示屬性的取值,也可以表達為entity.attribute=value,多個狀態形成一個狀態的集合states.
定義2.組合狀態S={s|s∈States},是一個原子狀態的集合.從場景上下文中提取的狀態稱為前置狀態(preState),從結果中提取的狀態稱為后置狀態(preState).
例如,表1 中scenario1 分別提取前置狀態S和后置狀態S′,S={(賬號.余額=balance),(卡.狀態=驗證通過),(ATM.現金儲備=enough)}(當描述狀態的短句中省略了屬性名詞時,則認為是某實體的“狀態”).S′={(賬號.余額=balance-cash),(卡.狀態=驗證通過),(ATM.現金儲備=enough)},(ATM.吐幣金額=cash)(系統.提示信息=取款成功).
定義3.狀態變遷t是一個三元組(S,event,S′),其中,S是前置狀態,S′是后置狀態,event∈Event表示事件.表示從組合狀態S通過事件event變換到組合狀態S′.多個狀態變遷組成了一個狀態變遷的集合,表示為T.
狀態變遷描述了從一個前置狀態通過事件發生變化到后置狀態的過程.一個變遷的目標組合狀態可能是另一個狀態變遷的源組合狀態,形成一個狀態序列,表示為
定義4.屬性集V={vi|i=1,2,…,K},是由K個實體-屬性v組成的集合,每個v是一個二元組(entity,attribute),表示一個實體的屬性,該屬性在不同的狀態會取不同的值.記為entity.attribute.
例如,表1 的scenario1,S的屬性集V={賬號.余額,卡.狀態,ATM.現金儲備},S′的屬性集V′={賬號.余額,卡.狀態,ATM.現金儲備,ATM.吐幣金額,系統.提示信息}.
定義5.場景屬性集scenarioi.V=V∪V′(其中,V是場景scenarioi的前置狀態屬性集,V′是場景scenarioi的后置狀態屬性集).
例如表1 中場景scenario1 的屬性集scenario1.V=V∪V′={賬號.余額,卡.狀態,ATM.現金儲備,ATM.吐幣金額,系統.提示信息}.
場景狀態補齊:對照場景的屬性集,S和S′可能缺少個別屬性的狀態信息,例如S中沒有描述(ATM.吐幣金額)和(系統.提示信息).為了保持一致,向S中添加這兩個屬性,并且賦一個NULL 值,表示對應的實體-屬性取值不確定.如S補充屬性和值后變為S={(賬號.余額=balance),(卡.狀態=驗證通過),(ATM.現金儲備=enough),(ATM.吐幣金額=NULL),(系統.提示信息=NULL)}.
定義6.功能特征屬性集N表示一個用戶故事中場景的個數.
狀態變遷圖生成:假設表1 中每個場景的前置狀態用Si表示,而后置狀態用表示,事件用eventi表示,則狀態序列集可表示為執行場景狀態補齊,6 個組合狀態如圖4 左側部分所示.如果場景中的組合狀態用點表示,狀態之間的事件作為一條有標記的邊,合并相同狀態,并添加一個起始狀態S0和空轉移的邊ε,連接每個狀態變遷的初始狀態,這樣,狀態變遷集表達為一個連通的狀態變遷圖,如圖4 右側部分所示.
故事描述、功能特征屬性和狀態變遷圖是一個功能特征節點的3 部分.通過關系連接起來形成一個系統功能場景.
定義7.一個功能特征節點是一個三元組(U,V,G),U也是一個四元組(title,role,mean,benefit)表示節點的用戶故事,V表示功能特征屬性集,G表示狀態變遷圖.
定義8.系統功能場景是一個圖.用二元組(N,E)表示.
·N是節點的集合,系統功能場景中的節點n∈N,是一個功能特征節點.
·E是一個故事關系集合,系統功能場景的邊edge∈E,是一個三元組(n1,e,n2),表示節點n1到目標節點n2存在關系e.關系e有3 種類型:合作關系、執行依賴關系和近義關系.執行依賴關系有方向,而另外兩種關系沒有方向,表示兩個故事互相具有此種關系.

Fig.4 Function-scenario description of the cases in Table 1圖4 表1 案例功能場景表示
寫用戶故事一般從復雜用戶故事開始,即領域客戶先寫一個“大”用戶故事,表達相對宏觀的需求.然后通過分解用戶故事逐步使故事具體化,形成一些小故事[3].例如,ATM 自動取款機辦理業務是一個復雜的故事.表1 的例子講述了作為一個持卡人,在ATM 機上取款的故事.假設還包括另外兩個故事:持卡人驗證身份,持卡人查詢余額,詳見表3(省略了場景中的細節).

Table 3 The description of two sub user stories for ATM business表3 ATM 自動取款機業務的兩個子故事
持卡人取款、持卡人驗證身份和持卡人查詢余額,這3 個用戶故事具有相同的角色,都涉及賬號、卡狀態、ATM 機等領域概念,而且在In order to 描述字段中隱含了用戶故事之間的依賴關系.根據這些概念之間的聯系,可以發現這3 個用戶故事之間的關系,得到后文圖5 所示的系統功能場景圖.
用戶故事場景抽取以一個帶場景的用戶故事為輸入,通過故事結構文檔生成、狀態變遷提取、狀態變遷圖生成,將用戶故事表達為功能場景表示.本節介紹用戶故事場景抽取生成功能場景表示的過程.
帶場景的用戶故事是一個有標簽的文檔,每個標簽后面的信息表達特定的語義,滿足表4 用戶故事文檔描述規約.
按照表4 規約從用戶故事提取字段信息,存放在故事結構文檔.后文圖6 所示為表1 中用戶故事的結構文檔表示.

Fig.5 An example of a feature-scenario圖5 系統功能場景示例

Table 4 The description rule of a user story表4 用戶故事文檔描述規約
為了生成狀態變遷圖以及提取功能特征屬性集,狀態(實體-屬性-值)首先從故事結構文檔中“state”標簽后面的短句中提取.使用自然語言分析工具(HanLP[21]),對狀態描述語句進行分詞、詞性標注和依存句法分析,然后與句法模板(表2)匹配,根據匹配句型找出實體、屬性和值.例如,“賬號的余額是balance”與“名+名+是+名”狀態模式匹配,進而找出狀態{賬號.余額=balance}.
從用戶故事中識別所有狀態,并根據狀態表達語句的位置,分別存儲在preState 和postState 這兩個集合中.然后進行場景狀態補齊,得到統一的實體-屬性集,具體步驟如下.
·Step 1:從preState 和postState 中的每個狀態中提取實體-屬性,存儲到屬性集V和V′中.
·Step 2:取屬性集V和V′的并集,得到一個關于這個場景的屬性集scenario.V=V∪V′.
·Step 3:在preState 中補充實體-屬性scenario.V-V,并給scenario.V-V的實體-屬性賦NULL 值.在postState中補充實體-屬性scenario.V-V′,并給scenario.V-V′的實體-屬性賦NULL 值.
通過場景狀態補齊,preState 和postState 具有相同場景屬性集.提取event 字段信息,組成一個狀態變遷序列(preState,event,postState).

Fig.6 The json document of a user story in Table 1圖6 表1 故事結構文檔json 文件(部分)
上述過程應用于用戶故事的每一個場景,最終得到一個狀態變遷序列的集合.合并狀態變遷序列集合中相同的組合狀態(組合狀態State 1 和State 2 具有相同狀態數,State 1 中的所有狀態在State 2 中都能找到,且State 2中的所有狀態在State 1 中都能找到),然后添加初始狀態和轉換邊,生成狀態變遷圖.狀態變遷圖生成過程如下.
·Step 1:提取每個場景的狀態變遷序列,得到一個狀態變遷序列集合T.
·Step 2:對T中所有場景執行場景狀態補齊,得到功能特征屬性集feature.V.
·Step 3:匹配T中不同場景的組合狀態,如果有相同的組合狀態,則持行Step 4,否則,執行Step 5.
·Step 4:根據合并規則(見表5)合并狀態變遷序列.如果沒有違反合并規則,則轉Step 5,否則,報告錯誤.
·Step 5:增加一個空的狀態節點,作為起始節點.連接起始節點與合并后狀態序列集中所有沒有前驅的組合狀態節點,并在標記事件的邊上添加ε.形成一個狀態變遷圖.
狀態變遷圖表達了用戶故事在不同上下文情況下意圖是否達成的狀態結構化組織方式.狀態變遷圖是一個有向無環圖,從起始點出發,可以遍歷所有狀態.使用狀態變遷圖可以幫助開發者了解與功能實現相關的業務流,同時也便于開發和測試.
表5 列舉了狀態變遷序列合并的6 種情況,其中,(a)表示合并之前兩個狀態序列的對應關系,(b)表示合并之后的情況.虛線表示兩端的節點狀態相同,能夠合并在一起.這6 種情況中,1~3 能夠正常自動合并,4~6 可能存在語義表達沖突,不能進行合并.

Table 5 The rules for merging states sequence表5 狀態變遷序列合并規則
功能場景表示除了包含功能場景屬性集和狀態變遷圖外,還包括故事描述.故事描述由用戶故事名、角色、意圖及收益4 部分信息組成,分別從故事特征字段文檔的“title”和“narrative”字段中提取.結合功能屬性特征集提取和狀態變遷圖生成,生成功能場景表示如算法1 所示.
算法1.功能場景表示生成.
輸入:一個用戶故事的故事結構文檔fileInput.json;
輸出:一個功能場景表示fsNode.
偽代碼:


系統功能場景包括一組功能特征節點和它們之間的關系,以系統的視角呈現用戶故事需求.本節介紹用戶故事關聯關系挖掘方法、多個用戶故事之間的沖突檢測以及系統功能場景生成與更新.
用戶故事之間可能存在的關聯語義體現在圖7 所示的用戶故事概念當中(源自于圖2).圖中虛線框表示在圖2 用戶故事概念的基礎上細化(分解成分),增加功能場景屬性集,灰色底紋部分表示暫時不考慮的概念.

Fig.7 The hierarchical relation of concepts in a user story for constructing relationship圖7 用戶故事關系概念元素層次關系
用戶故事u1,u2之間的關系包括合作關系、執行依賴關系以及近義關系.合作關系表達一組故事通過合作共同完成一個較大規模的故事.這些故事一般具有相同的角色和客體(功能的操作對象),功能特征屬性集有重疊.執行依賴關系表明一個故事的執行依賴于另一個故事的實現.這些故事一般在功能描述上有相關性,如在“收益”中描述功能依賴.近義關系表明故事具有相似的含義,表現在用戶故事概念模型的各部分都很相似.
1)合作關系關聯強度計算
合作關系關聯強度從角色維度、功能客體(意圖中客體)和功能特征屬性相關度這3 個方面加以度量.假設u1,u2分別表示兩個用戶故事,r1,r2分別表示這兩個故事的角色,o1,o2分別表示這兩個故事意圖中的客體,V1,V2分別表示這兩個故事的功能特征屬性,則用戶故事u1,u2的合作關系強度Sco(u1,u2)等于角色相似度、功能客體相似度與共同功能特征屬性比例的加權平均,計算公式如下:

本文綜合使用自然語言分析工具中基于詞向量的相似度計算方法[22]和語義相似度[21]的方法計算兩個單詞的相似度.α1+α2+α3=1,Sco(u1,u2)是一個0-1 之間的小數.
2)執行依賴關系關聯強度計算
執行依賴關系關聯強度與功能特征屬性和“收益”中描述的功能(動作+客體)是否關聯到另外一個用戶的功能(“意圖”中動作+客體)相關.假設f1,f2分別表示故事u1,u2的功能,其中,fi=(actionverb,object)(i∈{0,1}).分別從“意圖”的動作和客體中獲取.cf1,cf2分別表示收益的描述中提到的功能,同樣表達為cfi=(actionverb,object(i∈{0,1})).需要在fi和cfi之間做一個映射,計算它們的關聯強度,稱為功能相關度.舉例如下:如第2.3 節中“持卡人查詢余額”的用戶故事中“收益”字段描述了“當知道賬號余額,可以取現金”,而“持卡人取現金”的用戶故事中的“意圖”描述了“在ATM 機上取現金”.借助自然語言分析方法(分詞、詞性標注、依存文法分析[23])可以得到cf1=(取,現金),f2=(取,現金),它們的功能相關度為1.
功能相關度與動詞及客體相關,假設fi.a表達動作,fi.o表達客體,u1“意圖”中的功能描述與u2“收益”中的功能描述的功能相關度sim(f1,cf2)使用如下公式計算:

執行依賴關系關聯強度Sde(u1,u2)等于共同功能特征屬性比例與功能相關度的加權平均,計算公式如下:

其中,β1+β2=1,Sde(u1,u2)是一個0-1 之間的小數.
3)近義關系關聯強度計算
近義關系關聯強度從4 個維度度量近似關聯強度:故事名、角色、功能特征屬性集以及意圖(動作、客體).假設t1,t2分別表示兩個故事的標題,m1,m2分別表示兩個故事的意圖,計算意圖的相似性參見公式(2).
近義關系關聯強度Ssi(u1,u2)等于上述4 部分概念的加權平均,計算公式如下:

其中,γ1+γ2+γ3+γ4=1,Ssi(u1,u2)是一個0-1 之間的小數.
沖突是指用戶故事之間存在語義冗余或不一致,語義冗余是指兩個用戶故事表達了基本相同的語義,需要從故事描述、業務功能屬性描述以及場景(狀態變遷圖)這3 個方面分別檢查.不一致是指兩個用戶故事的場景描述的狀態變遷存在邏輯問題,如表5 中的情況4~情況6.
對于兩個用戶故事u1=(U1,V1,G1)和u2=(U2,V2,G2),其中,U表示故事描述,V表示功能特征屬性集,G表示狀態變遷圖.沖突檢查需要分別檢查這3 個部分的匹配情況.具體過程如下.
1)當角色相同且意圖相近時,認為兩個用戶故事的故事描述匹配.角色和意圖是否相近的判別方法見第4.1 節.
2)如果兩個用戶故事的功能特征屬性集相同V1=V2,則兩個用戶故事的功能特征屬性集匹配.
3)匹配狀態變遷圖的節點,通過檢查合并規則發現沖突.將G1中的每個狀態與G2中的狀態進行匹配,如果發現了匹配的狀態,再查看該狀態相關聯的狀態變遷是否匹配,然后應用表5 中的合并規則,檢查是否有沖突發生.
沖突檢查算法如算法2 所示.
算法2.用戶故事間的沖突檢查.
輸出:沖突檢查結果.
偽代碼:


系統功能場景生成以一組功能特征表示為輸入,計算機自動推薦關系,用戶通過關系確認,最終生成系統功能場景.生成過程主要步驟如下.
·Step 1:輸入一組帶場景的用戶故事,執行用戶故事場景抽取,生成一個功能特征節點集合.
·Step 2:使用用戶故事關系挖掘方法計算故事之間的合作關系、執行依賴關系以及近義關系的關聯強度,根據關聯強度的值,將大于閾值(根據領域問題和用戶故事數據集的規模設定)的候選用戶故事關系反饋給領域用戶(關聯強度值越高,相關度越高).
·Step 3:對于存在近義關系的故事,檢查是否存在沖突.如果有沖突發生,報告給開發者.
·Step 4:領域用戶根據用戶故事關系挖掘的候選關系結果確認用戶故事之間的關系.
·Step 5:按照確認的用戶故事關系,在功能特征節點間建立關聯邊,生成系統功能場景.
系統功能場景更新也是一個交互的過程.領域用戶提出刪除、修改和添加新用戶故事的申請.對于刪除和修改的用戶故事,自動化的方法是首先檢索關聯故事,反饋給領域用戶確定刪除和修改的故事.如果領域用戶確認刪除故事,則自動化地刪除故事及其關聯的邊.對于修改后的用戶故事或新加入的用戶故事,自動化方法首先將用戶故事結構化,然后識別依賴關系,進行沖突檢查后反饋可能添加的位置信息.領域用戶最終確認添加位置,將新增的用戶故事加入到系統功能場景中.
本節結合在線購物系統案例,討論系統功能場景構建及沖突檢測的可行性.包括案例介紹、實驗結果展示以及實驗結果分析與討論這3 個部分.
我們以“在線購物系統”的帶場景的用戶故事集為案例,開展實驗研究.首先由3 名同學組成了一個研討小組.分別從客戶、商業用戶和快遞員3 類用戶的角色,使用本文中描述的帶場景的用戶故事的模板和表2 中的推薦句型,撰寫和提交需求文檔.這3 名同學共提交了24 個用戶故事,共計57 個場景.業務功能操作客體(用戶故事功能操作的對象)包括賬號、商品、訂單、聯系人信息以及購物車等.表6 為收集到的初始版本用戶故事相關信息統計表.

Table 6 Characteristics of a set of user stories for a case study表6 案例用戶故事集相關信息
為了驗證本文提出的系統功能場景生成方法和表達用戶故事之間關系的可用性,使用Java 語言開發原型系統.該系統交互式地生成系統功能場景,包括3 個步驟:首先,系統推薦3 種用戶故事關系(合作關系、執行依賴關系以及近義關系),然后,領域用戶從推薦的關系中選擇他們認為正確的關系,最后,系統根據用戶確認的關系結果生成系統功能場景圖并反饋給領域用戶.同時,系統檢測并反饋近義關系中可能存在的沖突.圖8 所示為原型系統推薦用戶故事關系和領域用戶確認關系過程的截圖,圖9 所示為原型系統生成的系統功能場景圖及存在近義關系的用戶故事沖突反饋結果截圖.

Fig.8 Screenshot of user-interface about recommendation and confirmation of user stories' relationships圖8 用戶故事關系推薦與確認交互界面截圖

Fig.9 Screenshot of system function-scenario graph and the results of conflict defections圖9 系統功能場景及沖突檢查結果界面截圖
圖9 所示的“系統功能場景展示”表達了3 種用戶故事關系,其中,合作關系(由無向邊連接)將24 個用戶故事連接成9 個連通區域,分別對應表6 中角色執行業務客體的功能需求.每個連通區域中的用戶故事共同合作實現具體“角色”針對一個具體“業務實體”(功能操作客體)的功能需要.例如,“1 和2”(“注冊賬號”和“登錄賬號”)表示用戶對賬號的功能需要.執行依賴關系(由單向有向邊連接)將24 個用戶故事連接成6 個連通區域,分別對應于賬號、商品、訂單、聯系人信息以及購物車等業務實體的用戶故事(功能)執行依賴關系,表達客戶對購買商品、快遞員配送商品、客戶添加聯系人信息、客戶修改購物車、客戶管理訂單以及商業用戶管理商品這6個功能執行次序.近義依賴關系(由雙向有向邊連接)表示用戶故事有可能存在語義冗余,可以考慮對這些語義冗余進行合并.例如,案例中分別對客戶、商業用戶以及快遞員描述了注冊賬號的用戶故事,它們之間有著較高的冗余語義,可以考慮將3 個故事合并.
為了檢驗用戶故事之間關系推薦的準確率和召回率,以及3 種關系推薦時不同的反饋閾值(實驗參數)的影響,進行了實驗分析.準確率表明推薦關系的準確性,等于用戶確認的數量除上系統推薦的數量.召回率表明推薦關系的完整性,等于用戶確認的數量(系統推薦正確的數量)除上用戶確認的數量與用戶添加的關系數量的和.推薦關系反饋閾值表示當兩個用戶故事之間的關聯程度大于反饋閾值時,該關系顯示在推薦列表中.

Table 7 Statistic table of precision and recall about user stories' relationships that are recommended by system表7 用戶故事關系推薦結果準確率與召回率統計表
表7 表示3 種關系在不同推薦閾值時準確率和召回率的統計結果,其中,合作關系及近義關系有較好的準確率和召回率.執行依賴關系相對較差,原因是每個用戶故事及其場景在表達上一般相對獨立,很難從有限的信息中挖掘執行先后關系.結合領域知識可以得到更好的效果[24-26],將在后續工作中進行嘗試.
推薦關系和沖突反饋結果的準確率還受到以下幾個方面的影響.
(1)用戶故事描述語句格式的規范性:規范的語句格式便于應用標準模板提取用戶故事概念語義,形成正確、完整的功能特征屬性集以及狀態變遷圖,有助于準確地建立關聯.
(2)多人合作時領域術語的統一:領域術語統一對計算關系語句同義性起著重要作用.如兩個需求提供者分別用“賬號”和“帳號”表達同樣的指代,但是它們的相似度并不是1.
(3)In order to 字段中執行依賴語義的表達:本文描述的執行依賴關系的推薦依據主要來自于用戶故事中In order to 字段的描述信息.如果領域用戶在寫需求時省略了此項,或者沒有表達相關語義,本文的方法不能準確地發現它們之間隱藏的執行依賴關系.只能通過人工添加的方法加入到系統功能場景.
(4)自然語言處理方法的影響:本文使用開源工具HanLP 進行自動化的自然語言分析,包括分詞及依存句法分析.分析結果對關系的推薦結果有一定的影響.另外,計算詞語之間的相似度是推薦挖掘的基礎.但目前對詞語中語義(特別是面向領域問題)的相似性計算效果并不理想.原型系統結合基于詞的語義距離、NGram 和word2Vec 的方法計算詞語之間的相似度,得到較好的效果.
敏捷開發方法由于具有快速應對需求變更的能力,被廣大軟件產品開發團隊使用.團隊成員之間的需求理解以及不同迭代版本的需求管理是有效發揮敏捷開發優勢的關鍵.為解決這些關鍵問題,近年來,研究者們在用戶故事與建模以及需求變更管理方面開展了一系列研究工作.
6.1.1 用戶故事與建模
在80%的敏捷方法中,使用用戶故事表達客戶對系統的需求[16,27,28].好的用戶故事應相互獨立,涉及小的功能,且需求可評估可測試[1-3,15,16].多個用戶故事之間存在關聯,它們組合在一起,形成完整的系統需求.這需要開發人員能從系統的角度識別出一組用戶故事之間的關系.很多工作主要提供可視化工具,以便于開發人員瀏覽和編輯需求[11,12,29].
Wautelet 等人[12]提出建立Use-case 與用戶故事之間的映射關系,該方法將用戶故事中的角色映射到use case 中的actor,從意圖和收益中分解任務,抽取任務及目標作為Use-case 中的節點,并在目標與任務之間識別包含關系與擴展關系映射到use case 中.他們提供了圖形編輯工具[29],支持開發人員從用戶故事、Use-case 以及類圖3 個角度觀察需求.Mesquita 等人[11]提供了圖形編輯工具US2StarTool,支持將一組用戶故事映射為一個i*模型,幫助開發人員以系統的視角考察參與者如何達成目標以及目標之間的關系.Trkman 等人[10]提出從用戶故事中提取本體以構建業務過程模型(business process model),建立用戶故事之間的順序依賴關系.Wautelet[30]使用面向目標的方法建立多個用戶故事之間的關系.Lucassen 等人[9,31]提出,借助自然語言分析的方法從用戶故事中提取概念模型.他們總結出提取概念和關系的啟發式規則,并根據規則抽取概念并建立關聯關系.
這些方法都提供了建立用戶故事與系統模型間的映射關系的手段,但是由于用戶故事基本上是非結構化的,而且用戶故事描述的信息過于簡化,目前的方法大多通過可視化并結合人工建立用戶故事關系.本文提出的方法借助帶場景的用戶故事模型抽取與關系挖掘,以人機協同的方式半自動化地建立用戶故事之間的關聯.最終形成一個系統的視角,幫助開發者了解用戶故事之間的關系以及支持迭代的模型增加與修改.
6.1.2 需求變更管理
需求演進由需求變化引起[24,32],需求變化包括增加需求、刪除需求或者修改需求.當需求規模較大時,分析和評估跨版本的需求變更以及隨之帶來的管理成本和風險變得更加困難.
一些研究工作著眼于收集需求數據,然后分析需求變化,進而發現新需求.Galvis 等人[33]從一組相關軟件的需求反饋中自動提取主題,建立主題模型,用于分析變化的需求以及創新的需求.Schneider 等人[34]提出識別軟件版本演化過程中用戶對軟件使用的反饋或建議,通過分類和整理從中獲取新的需求.
為管理需求變化帶來的風險,Shi 等人[18]從具有演化特征的多個連續版本的需求數據集中學習變化規律,以預測后續版本中需求可能發生的變化.Anderson 等人[19]以航空電子工業案例為例開展實證研究,通過對進化趨勢和需求成熟度度量進化信息,以便理解需求演進.
在敏捷開發過程中,利益相關者之間的頻繁交互導致迭代的需求過程,使得需求隨著時間的推移變得更加清晰,有利于加強與客戶的關系,并希望能以較少的時間投入,得到明確的系統需求[35].需求變更管理是其中的一個挑戰性問題.目前需求變更管理大部分是通過維護產品的功能列表和索引卡來跟蹤需求變化[2,36]的,對于一個規模較大的系統,要耗費大量的人力.Ajmeri[20]提出使用需求分析平臺,支持多用戶間的協同,促成敏捷需求的識別、討論與定義.該方法提出使用領域知識語料(包括核心用戶故事,行業規則,use case,數據模型,原型等),幫助客戶、領域專家和其他分析人員能夠在平臺上修改和增加領域知識以適應具體項目的需要,提高敏捷開發中需求變更的管理能力.目前,也有研究從群體用戶中采集需求,借助群體的智慧增進需求的理解,逐步提出更明確的需求,以支持需求的持續演化[37-39],如Ali 等人[37]召集一組學生扮演不同視角的用戶群體,從用戶故事、場景到use case 逐步提供明確的需求.最終得到一個完整的系統需求.
在需求變更管理中,每次需求變更都是一次繁瑣的過程,涉及識別需求變更、變更分析及變更成本分析等步驟.我們的方法以系統模型為基礎,提供一種人機協同的方式,支持需求變更.該方法同時考慮了需求變化可能會產生的沖突,根據沖突檢查規則,將發現的沖突反饋給使用者.最終由使用者決策如何消解這些沖突.
在敏捷開發過程中,需求并不是事先定義好的,而是通過利益相關者之間的頻繁交互,隨著迭代開發過程逐步形成的.開發者理解領域用戶提交的需求仍然是敏捷開發的瓶頸之一.一方面,用戶故事所表達的信息有限,開發者要從功能實現的角度理解用戶故事,需要花費很長的時間與領域用戶討論確認.另一方面,多個用戶故事孤立地表達了領域用戶的期望,缺乏系統的視角,開發者要理解用戶故事之間的關系,推斷其優先級也存在難度,導致系統模型構建上的困難.此外,當用戶修改或提交新的用戶故事時,確定新增用戶故事在當前系統中的位置,以及檢查其與原有用戶故事的沖突,都是繁重的工作.
為了減輕開發者的負擔,發揮領域用戶在特定領域上的專家優勢,從而實現高質、高效的系統需求管理,本文提出并設計了一種人機協同的系統故事模型創建及更新方法.面對大量用戶故事數據,讓計算機自動地進行需求抽取和關聯關系挖掘.領域用戶對挖掘結果進行確認,人機合作完成系統功能場景圖的構建和更新.案例研究表明,本文提出的用戶故事整合方法具有較好的效果,具備一定的可行性.
需求提取與系統需求整合的質量與用戶故事表達的質量相關.自然語言描述固有的模糊性,領域用戶也不了解如何從獨立的用戶故事中整合出系統的功能需求,是影響需求質量的主要原因.從系統視角進行需求質量的檢查與評估,以及提供一個支持敏捷團隊需求協商的可視化平臺,是后續工作中要解決的問題.
此外,在需求演化過程中,需求變更可能會對原來版本的需求產生沖突,我們目前的做法是根據沖突發現規則生成沖突報告.根據用戶故事之間的關系的性質和領域知識可以給沖突消解提供參考,將更有效地指導需求工程師解決沖突問題,這是另一個后續工作中要解決的問題.