楊德仁,王曉峰,劉建平,韓 強
(1.寧夏醫科大學 理學院,寧夏 銀川 750004;2.北方民族大學 計算機科學與工程學院,寧夏 銀川 750021)
軟件工程的難點在于軟件的復雜性[1]和軟件需求的不確定性[2]。前者可通過推遲實施及規范化軟件過程加以緩解[3],后者可通過應用敏捷框架來解決[2,4]。但規范化軟件過程容易導致設計麻痹問題,敏捷化會導致論域模糊化等問題。以用戶故事(User Stories)為線索,有機結合敏捷框架與傳統軟件過程不失為一種選擇性優化方法,其應用實踐(即工程實踐與教學實踐)值得探索[4]。
針對軟件開發商過分注重軟件開發周期的規劃與文檔化,而忽視了至關重要的問題,即如何滿足客戶需求,2001 年17 位軟件領域的專家提出了敏捷概念,開啟了敏捷開發的新紀元,并頒布了敏捷開發宣言。該宣言倡導:個人與交互勝過過程和工具;可工作的軟件勝過全面的文檔;客戶合作勝過合同談判;響應變化勝過遵循計劃,其中3 條涉及客戶(用戶)及其需求。根據該宣言還制定了12 條敏捷原則[5],其中大多數原則涉及客戶(用戶)及其需求或敏捷團隊,諸如:盡早及持續性交付有價值的軟件以滿足客戶需求;擁抱需求變化,即使在開發后期;通過敏捷過程以駕馭變化,為客戶贏得競爭優勢;在執行項目過程中,業務人員和開發人員必須每天協同工作;面對面的交流是向開發團隊內外傳遞信息最有效率且效果最好的方法;敏捷過程提倡可持續開發,投資者、開發者和用戶應維持穩定的開發速度;最好的架構、需求和設計來自于自組織團隊;團隊需定期反省如何能更有效地工作,然后相應調整其行為。其余原則涉及到產品的敏捷交付,諸如:頻繁地交付可工作的軟件,交付周期為幾周到幾個月,周期越短越好;項目建設要圍繞著有推動力的團隊成員,提供其所需的環境和支援,并給予信任;可工作的軟件是衡量項目進度的主要標準;持續追求技術上的精益求精與良好的設計,以增強敏捷性;以簡潔為本,這是盡量減少不必要工作量的藝術。
因此,敏捷框架的核心是以人為本的敏捷團隊,需要用戶全程參與,以克服傳統軟件過程因用戶的有限參與而導致軟件產品與其需求不一致的問題。用戶參與的驅動力之一是講好用戶故事,從而更好地探索軟件需求及其解決方案[2]。例如,在Scrum 框架中把用戶故事作為其產品訂單(Product Backlog)項或沖刺訂單(SprintBacklog)項[6],在看板中把用戶故事作為工作流中的在制品(Work In Progress/WIP)[7]。正是基于用戶故事,Scrum 團隊可更好地評估與規劃sprint 計劃,以實現準確的預測及更好的敏捷性,看板團隊還可進一步細化其工作流。
用戶故事及其成功應用奠定了其在敏捷框架中的核心地位,也啟示著其在傳統軟件開發過程中的擴展性應用,促進了敏捷框架與傳統軟件開發過程的融合。但實際上,應用用戶故事并非一蹴而就,相關機制需要不斷進行拓展與細化。
在軟件工程中,用戶(User)指軟件的使用者。用戶概念很重要,其是建模的視角之一,但也總是模糊不清,極易與客戶、角色等概念混淆。
在敏捷框架語境中,根據用戶故事的定義(參見2.1節),用戶基于角色敘述使用系統的故事。用戶是個抽象概念,不能一概而論,用戶因其角色而異。例如,業務人員及其客戶在使用購物軟件時便扮演著不同角色。
UML 規定了用例用于捕獲軟件(系統)需求,即系統應該做什么,其關鍵概念是參與者(Actors)、用例和主題[8]。主題代表用例所應用的待建系統,與該主題交互的用戶、硬件及其它任何系統角色都被視為參與者。參與者并非具體的物理實體,而是實體所扮演的角色。實體包括人類用戶、外部硬件或其他系統。因此,一個實體可扮演多個角色,一個角色可由多個實體扮演。
Dines[9]提出軟件工程的三段論,即(業務)域工程、需求工程和軟件設計,建議在開發早期要盡力羅列(業務)域涉眾(Stakeholder)及其角色和權益,并基于涉眾視角進行建模。其還指出在整個工程期間,要基于具體論域,例如需求域、分析域和設計域,不斷更新與修正涉眾角色,尤其在需求啟發階段。
Peter 等[10]提出彩色UML 建模方法,并認為(業務)域通用模型包括4 種基本架構型(Archetypes),并用不同顏色表示。其中,時刻—時段(Moment-Interval/MI)代表待處理或跟蹤在某時刻或某時段內發生的業務,以提醒建模者尋找問題域中的重要時刻或時段,用醒目的粉色表示,因其將各組件聯系在一起,處于核心與靈魂地位。角色(Role)代表參與者的參與方式,用黃色表示。描述(Description)類似于目錄和類別,用藍色表示。角色扮演者(PartyPlaceThing/PPT)指個人或組織、地點或事物,用綠色表示。PPT 和角色具有一對多與多對一關系,例如:一個事物在制造過程中扮演一個角色,而在營銷過程中又扮演另一個角色,一個人可能既是雇員又是客戶,一個店面既可以是零售店,也可以是批發店。
Jacobson 等[11]提出的用例2.0 軟件方法以講故事和按片構造系統為原則,并把用戶故事定義為用例切片以驅動軟件開發。在用例2.0 中,用戶故事被作為用例切片進行迭代開發,而失去了探索軟件需求的意義。
在上述方法中,角色的體現形式及應用范圍不一,具體如表1 所示。

Table 1 Roles and corresponding manifestations and applications表1 角色及其體現形式與應用范圍
Resketi 等[12]提出一種概括用戶故事的方法,借助于修正的詞和動詞解析器,提取關鍵字與關鍵動詞的集合,自動生成用戶故事,之后由專家進行改進,以備在未來開發相似的系統中重用。
用戶故事作為探索需求的基礎與手段,也被擴展到傳統軟件開發過程中。基于MDA 的模型轉化理念[13],采用自然語言處理技術,Meryem 等[14]提出一種將用戶故事轉換為用例的過程,而忽視了用戶故事與用例不在一個抽象層次。Samia 等[15]探索直接從用戶故事提取設計層次類圖的方法,但這種類圖缺乏軟件的控制類和窗體類,其完整性值得商榷。
上述研究為應用用戶故事奠定了基礎,但除Peter 等[10]的架構型和Dines[9]的三段論外,其它研究均未涉及業務域。認知與解決軟件的復雜性必須基于其應用的業務域,這是彩色UML 建模、領域驅動的設計[16]及三段論等新型軟件開發方法所提倡的。
基于筆者提出的雙論域層次化軟件建模框架[17],本文擬探索用戶故事的來源、擴展及其建模機制。
在軟件開發與項目管理過程中,需要以日常語言或商務用語編寫句子式的用戶故事。其只要求寫出最有價值而不能被忘記的用戶期望,以幫助確定軟件需求、估算工作量以及與客戶溝通。
用戶描述是敏捷框架中最小的工作單元,其是從軟件用戶角度表達的最終目標,而不是特性(用戶需求)。用戶故事是從最終用戶或客戶角度編寫的針對軟件特性非正式、一般的解釋。用戶故事的目的是闡明一項工作將如何向客戶交付具體價值。
用戶故事用簡單語句來表示,其定義及模板為:As a[persona],I[want to],[so that][2,4,7],即:作為<某角色>,我<想做>,<以實現>。其語義如下所述:
作為某角色:描述在為誰建造軟件,這不是頭銜職位,而是人物角色。團隊應該對該角色有共識,并希望采訪他以了解其工作方式。
想做:描述用戶意圖,即要達到的目的。其并非使用功能,也無實施細節,例如圖形用戶界面。
以便:描述待做的事情要符合的大局,即總利益或要解決的大問題,這也是衡量其優先度的標準。
值得注意的是,一個用戶故事只能有一個用戶角色且只做一件事,以便實現一個用戶目標。
用戶故事描述用戶操作軟件的簡單情境,以便開發者與客戶進行有效溝通,并盡快貼近用戶真實需求。通過這種對使用情境的描述,客戶可以輕松排定其優先順序,即按照重要性依次為:必需部分(Must Have)、應有部分(Should Have)和最好有部分(Nice to Have)。在敏捷迭代過程中,先做必需部分,再做應有部分,可暫時不做最好有部分[4]。
用戶故事有助于將關注點從編寫需求轉移到討論需求。除書面語句外,其作為啟發需求的手段,本身只是一個約定,需要與用戶展開一系列對話以探索并澄清需求。因此,Jeffries 等[18]總結了開發用戶故事的“3C”原則,即卡片(Card)、對話(Conversation)和確認(Confirmation)。要求把用戶故事寫在記事卡上,以記錄概述、估算工作量等,在計劃或估算時則需要故事的細節性對話,以測試與驗收方式確認故事的完整性和正確性。
用戶故事應具備6 個屬性,即獨立性、可協商性、有價值性、可預測性、短小精悍以及可測試性。Bill 使用這些屬性的首字符縮寫詞INVEST 表示用戶故事的評估標準[19]。
獨立性:盡可能避免故事之間產生依賴關系,否則會導致優先級和規劃問題。
可協商性:故事是可協商的,不必是書面合同或者需求。
有價值性:讓用戶編寫故事,確保故事有價值。
可預測性:開發者應能預測故事規模以及實施所需時間。
短小精悍:應在一個沖刺周期內完成,為此需要分解史詩級用戶故事,即epic。
可測試性:故事必須是可測試與驗證的。
用戶故事通常只是口頭性描述而無法精準反映出軟件需求,并因碎片化而呈現出一些局限性。具體而言,一是在現實中用戶所要非所需,即使所要是所需,軟件需求也會隨著市場變化而改變;二是在設計系統前,用戶故事其實只是用戶期盼;三是用戶故事沒有包含待更正的系統缺陷;四是層次不明,在系統開發之前,其實只有業務工人及客戶,即用戶的體現因其論域而異;五是用戶故事只是零碎的使用情景設想,抽象層次不高,容易陷入細節而難免顧此失彼[4],用戶故事也不同于用例,充其量只對應于用例的常用路徑,而沒有顧及用例的備用路徑和容錯路徑;六是用戶故事中的用戶與業務脫節而無法溯源。
因此,作為軟件需求的探索機制,用戶故事及其應用需要進行向上溯源與向下擴展實踐探索。
針對用戶故事的上述局限性,有必要探究其在軟件開發過程中的各種體現形式及其實踐機制,以及源泉和演化機制。
若只從軟件使用層面描述用戶設想,用戶故事則顯得唐突和不足。其實,用戶故事并非只是涉及軟件用戶的故事,因此“用戶”應擴展為“角色”。遠離業務的用戶故事無助于確定軟件需求,況且在業務層面上軟件用戶角色尚不存在,只有客戶角色和業務工人角色。客戶有業務需求,業務工人有滿足該需求的責任和義務,可借鑒銷售員角色加以實施。
在軟件需求層次,用戶有使用軟件的宏觀需求,即軟件功能。用戶來源于上述客戶和業務工人,此外還來源于軟件維護人員,而這種宏觀需求不能脫離其業務語境。在軟件分析層次,用戶有使用軟件的具體路徑,這便是傳統用戶故事或用例事件路徑的內涵。如上所述,在用例2.0中,這種用戶故事被定義為用例切片[11]。在實施層面,開發者通過編程以滿足用戶故事,測試者檢查軟件功能及其缺陷。其中,測試者來源于軟件用戶和開發者。
經上述拓展與細化,形成了一種擴展的用戶故事(an Extended User Stories/EUS),既體現在不同層面(論域),又被分解為各論域中的相應角色,例如業務層面的客戶與工人,以及軟件層面的用戶、開發者與測試者,如圖1、圖2 所示。
相應地,這種擴展的用戶故事格式應有所調整,例如:作為<客戶>,我<想>,<以便>;作為<業務工人>,<我想>,<以便>,依次類推。值得指出的是,這種故事還應與其論域及層次性相吻合。

Fig.1 Schematic diagram of RUS and its application圖1 RUS 及其應用示意圖

Fig.2 Schematic diagram of roles’overlap圖2 角色重疊性示意圖
基于圖1 所示的角色來源及其重疊性,“用戶”角色的演變歷程如圖3 所示。軟件用戶來源于客戶和業務工人,測試者來源于開發者和用戶。

Fig.3 Schematic diagram of“user”role and its evolution圖3 “用戶”角色及其演變示意圖
由圖3 可知,有些角色出現在不同層次上,其相應的故事粒度也不同,換言之,EUS 具有層次性。例如客戶和工人出現在業務域的不同抽象層次上,其故事即要做的事情和目的則各不相同,在軟件域中的用戶故事也一樣。參見本文3.3 節的實踐集及其案例中的論述。
在軟件工程項目實踐與教學實踐中,以EUS 為線索驅動軟件開發,相關路徑需要作進一步探索。
3.3.1 EUS 工程實踐路徑
在業務域,業務客戶和業務工人是關鍵角色,有必要確定客戶的業務需求和業務工人的業務服務。在軟件需求域,軟件用戶是關鍵角色。基于客戶、業務工人和軟件管理者等視角,確定用戶角色及其軟件需求,這種需求是高層次的抽象需求。在軟件分析域,讓用戶敘述傳統意義下的用戶故事,并實施優先度排序。
若有必要,在設計域,設計師設計軟件開發的藍圖,例如面向對象的靜態模型(類圖)、動態模型(序列圖和狀態機圖)和數據庫表模型等。在實施域(編碼和測試),開發者(程序員)進行編碼,測試者制定測試案例并根據軟件分析域中的用戶故事(用例切片)進行測試,以發現其缺陷。
3.3.2 EUS 教學實踐路徑
在軟件工程課程實踐中一般通過分組實施課程項目,以培養團隊的協作精神。根據項目需要,小組成員在各個論域中扮演不同角色,以便講好相應故事。若扮演角色有困難,可采用業務域的實踐集(參見3.3 節)或(頭腦)事件風暴會議的形式[20]。
除扮演角色外,項目小組還應設置組長和秘書角色,以便協調團隊工作并記錄設計結果。
實踐集是敏捷框架的關鍵要素之一,有助于克服傳統軟件開發過程中的設計麻痹問題[2]。論域建模,即業務域、需求域、分析域和設計域建模都需要相應的實踐集[4]。現以業務域為例,探索并給出其實踐集。
3.4.1 業務域實踐集框架
在業務域,用戶角色包括顧客、業務工人(可細分為主控業務工人、輔助業務工人)等,這些用戶故事描述相關涉眾(或稱為參與者)在業務域中的關鍵行為。相關故事其實在描述涉眾及其需求或事務(動作),其中客戶故事分為業務需求故事和業務參與故事。實踐集主要包括以下內容:
(1)責任驅動設計。每個涉眾都有其需求或責任,在業務域中,實現客戶需求正是業務服務提供者的責任。各涉眾也有其責任或行為,主要分為事務級和動作級兩個層次[21]。
(2)業務域建模風暴。具體細化為業務目標建模、業務狀態建模、業務事務建模及其編排、業務事務分解及其動作建模等步驟。
(3)業務需求建模。基于客戶視角為客戶需求建模。
(4)業務狀態建模。基于業務實施過程中關鍵信息子(諸如單據和報表等)的變化,確定業務狀態及其轉化關系。
(5)業務事務建模及編排。為上述各轉化關系指定事務,通過事務的實施促使狀態轉化,同時識別事務實施者即執行人。事務其實隸屬于過程中的主體與變體,即人人都有責任。之后,確定事務順序和優先級別,一般由主控業務工人確定,如門診業務中的坐診大夫。業務事務其實是業務過程的高級抽象,因此還需要進行分解與細化,參見下述的動作建模。
(6)動作建模。參照事務三段論即準備、執行與遞交結果,將事務分解為動作集[21],再確定各動作執行者,其參考基線是價值鏈中的活動。動作還需要完善,如同函數需要參數化,動作需要業務對象和信息子,其結果是業務過程模型。其中,業務對象是軟件對象的基礎,而業務需求者和參與者、信息子及其信息化處理是獲取軟件需求的基礎。
除普適性業務語言外,業務域建模還可采用UML、BPMN 或CMMN,甚至便簽,其它域的實踐集可參照業務域的實踐集制定[17]。
3.4.2 醫院門診業務實踐集案例
以醫院門診業務為例,列出其擴展的用戶及其事務。擴展的用戶角色為:客戶即患者,主業務工人為坐診大夫,輔助業務工人為收費員、化驗員、技師和護士等。相應事務為患者就診、坐診大夫接診與治療、收費員收費、化驗員化驗、技師拍片或治療及護士引導等。
事務分解以化驗為例,坐診大夫開化驗單,患者繳費,化驗員化驗并給出結果[21],其它事務可據此進行相應分解。
軟件需求是軟件開發的基礎,而軟件需求通常難以確定,即使用戶也難以表述清楚,加上市場競爭等因素影響,軟件需求會不斷發生變化。在迭代開發的基礎上,敏捷開發旨在組建業務(用戶)代表全程參與的敏捷團隊以擁抱需求變化。敏捷框架已成為軟件開發的主流技術,旨在為用戶提供最大價值。團隊用普適(業務)語言交流,以不斷提供的產品增量衡量項目進展。但敏捷框架呈現出模型層次不明晰或縮水等現象,混淆了不同論域的元素,超出了人們理解與解決問題的極限,違背了抽象與層次化設計原理,可能會弄巧成拙,增加軟件的偶然復雜性,進而導致軟件開發陷入“大泥球”。若基于傳統軟件開發方法如責任驅動的軟件開發方法,融角色責任與軟件責任于一體進行探索,則不失為一種有益嘗試,將是未來研究方向之一[22]。
目前一些知名的IT 國際咨詢機構,如雅各布森國際、Rebecca Wirfs-Brock 協會都在進行敏捷方法與傳統方法融合實踐的探索及推廣。這種敏捷框架與傳統軟件開發過程的融合趨勢值得國內業界、學術界和教育界重點關注[17]。