學習寫需求分析

筆者本身是軟件工程專業出身,但是對如何寫需求分析仍然是一知半解,拿到需求,仍然不知道如何下手,才能達到寫需求分析的目的。

今天看到一篇文章,讓我受益良多,同時參考此文,筆者也嘗試寫了一個需求分析,一個小小的程序,居然寫了21頁,筆者自己都感到驚訝。

所以,我也來轉載一下此神文。

轉載之前,筆者還是列舉下自己在實際操作中碰到的一些問題:

1.UML類圖,類圖設計中的組合、聚合、複合等等一系列的關係其實是挺複雜,每次用,下次用還是忘,我就在想,這樣的類圖,如果是用戶來閱讀,能得到什麼。或者說,筆者還沒有真正的瞭解UML類圖的作用和寫法。

2.UML類圖,依然是UML類圖,比如有某個函數,我不知道將此函數,歸結到哪個對象內,似乎,放這個對象可以,放那個對象也可以。是否是對面向對象的設計還理解不夠深刻呢。

3.UML類圖,還是UML類圖,在這篇文章的最後部分,有列出,UML類圖也就是領域模型,是寫在每個功能塊兒之後的,那麼問題來了,如果我有兩個功能塊兒,都是使用到另一個功能塊兒,那麼這個另一個功能塊兒,應該拎出來單獨寫,還是前面兩個功能塊中,都要寫進入。反正筆者碰到的是個小程序,索性就把3個模塊兒合到一起寫了。

4.狀態圖,本文中似乎寫,狀態圖不是必須,那麼,在文檔中,狀態圖應該放在什麼位置體現。

5.行動圖,其實高級的流程圖,用於描述各個user-case之間是如何協調操作的。應該放在什麼位置寫。是否應該,整體和各個模塊的地方,都應該有行動圖呢。

6.非功能模塊,本文強調很重要,但,似乎並沒有描述到如何寫;

7.需求分析中,是否應該包含數據庫的設計,比如E -R圖之類的。

8最後,筆者認爲還需要對,領域驅動設計,做深入的研究,這個似乎對用戶自己也不清楚需求是什麼的時候特別適用,也適用於敏捷開發。


好了,開始轉載,轉載地址來源於 http://blog.csdn.net/u014605728/article/details/50884289?locationNum=2&fps=1.


又到新年了,日曆又要從2011年翻到2012年了,這使我有太多的感慨,進而勾起了對太多往事的回憶。過去的10年,毫無疑問是中國軟件業發展最快的10年。當我們剛剛畢業的時候,還在使用VB、PB開發一些簡單的數據庫應用,而現在卻幾乎看不到它們的蹤影,換來的是諸如J2EE和.NET這樣的大型web應用。而這期間,RUP、XP、敏捷開發、持續集成••••••一個接一個的新概念層出不窮,令人眼花繚亂。現在想來,恍如隔世。

但更令我印象深刻而難以忘懷的,是我親自經歷的、親眼目睹的、道聽途說的一個又一個的軟件項目,它們有的獲得了成功,但更多的是令人沮喪的失敗。套用一下大文豪托爾斯泰體:幸福的家庭都是一樣的,不幸的家庭卻各有各的不幸;幸福的軟件項目都是一樣的,不幸的軟件項目卻各有各的不幸;或者說,成功的軟件項目都是一樣的,失敗的項目卻各有各的問題。我常常在想,我們的項目開發到底怎麼了,進而把它們一個一個的剝開來深入分析,竟然觸目驚心。它們有的是需求的問題,有的是客戶關係的問題,還有設計的問題、技術的問題、時間管理的問題、人員培養的問題••••••但歸根到底更多的還是需求的問題。需求分析既是一份體力活兒,更是一份技術活兒,它既是人際交往的藝術,又是邏輯分析與嚴密思考的產物。正是我們在需求分析過程存在的巨大隱患,最終導致了那麼多項目的失敗。也許你認爲我在危言聳聽,好吧,我來舉幾個典型事例分析分析吧。

我的第一個故事來自大名鼎鼎的東軟。我在2005年接一個項目的時候,聽說這個項目之前是東軟做的。當時東軟在做這個項目的時候,整個過程經歷了10多次結構性的大變更,局部性的調整更是不計其數。據說某天早上,客戶對某個功能不滿意,他們不得不對幾百處程序進行修改。之後客戶對修改的內容還是不滿意,又不得不將幾百處修改重新改回來。最後這個項目導致的結果是,整個這個項目組的所有成員都離開了東軟,並似乎從此不願涉足軟件開發領域。多麼慘痛的教訓啊!我常常聽到網友抱怨客戶總是對需求改來改去,但客戶對需求改來改去的真正原因是什麼呢?當我們對客戶的需求沒有真正理解清楚時,我們做出來的東西客戶必然不滿意。客戶只知道他不滿意,但怎樣才能使他滿意呢?他不知道,於是就在一點兒一點兒試,於是這種反覆變更就這樣發生了。如果我們明白了這一點,深入地去理解客戶的業務,進而想到客戶的心坎兒上去,最後做出來的東西必然是客戶滿意的。記住,當客戶提出業務變更的時候,我們一定不能被客戶牽着走,客戶說啥就是啥。我們要從業務角度深入的去分析,他爲什麼提出變更,提得合不合理,我有沒有更合理的方案滿足這個需求。當我們提出更加合理的方案時,客戶是樂於接受的,變更也變得可控了。

第二個故事來自我自己的項目,一個早期的項目。在這個項目中,客戶扔給了我們很多他們目前正在使用的統計報表,要我們按照報表的格式做出來。這些報表都是手工報表,許多格式既不規範,又很難於被計算機實現。這些報表令我耗費了不少腦細胞,直到最終項目失敗都沒法完成。這件事留給我的深刻教訓是,不能客戶怎麼說軟件就怎麼做。客戶提出的原始需求往往是不考慮技術實現,基於非計算機管理的操作模式提出來的。他們提出的很多需求常常比較理想而不切實際,畢竟人家是非技術的。但我們作爲技術人員,需求分析必須實事求是的、基於技術可以實現的角度去考慮。那種“有條件要上,沒有條件創造條件也要上”的魯莽行事,結果必然是悲慘的。所以我們必須要基於技術實現去引導客戶的需求。同時,計算機信息化管理就是一次改革,對以往手工管理模式的改革。如果我們上了信息化管理系統,採用的管理模式卻依然是過去的手工模式,新系統的優勢從何而來呢?因此,我們做需求就應當首先理解現有的管理模式,然後站在信息化管理的角度去審視他們的管理模式是否合理,最後一步一步地去引導他們按照更加合理的方式去操作與管理。

2007年,我參與了一個集團信息化建設的項目。這個項目中的客戶是一個龐大的羣體,他們分別扮演着各種角色。從機構層次劃分,有集團領導、二級機構人員、三級機構人員;從職能角色劃分,有高層領導、財務人員、生產管理員、採購人員、銷售人員,等等。在這樣一個複雜場景中,不同人員對這個項目的需求是各自不同的。非常遺憾的是,我們在進行需求分析的時候沒有認真分析清楚所有類型人員的需求。在進行需求調研的時候,總是集團領導帶領我們到基層單位,然後基層單位將各方面的人員叫來開大會。這樣的大會,各類型的人員七嘴八舌各說各自的需求,還有很多基層人員在大會上因爲羞澀根本就沒有提出自己的需求。這樣經過數次開會,需求調研就草草收場。我們拿着一個不充分的需求分析結果就開始項目開發,最終的結果可想而知。直到項目上線以後,我們才發現許多更加細節的業務需求都沒能分析到,系統根本沒法運行,不得不宣告失敗。一個軟件項目的需求調研首先必須要進行角色分析,然後對不同的角色分別進行調研。需求調研的初期需要召開項目動員大會,這是十分必要的。但真正要完成需求分析,應該是一個一個的小會,1~3個業務專家,只討論某個領域的業務需求,並且很多問題都不是能一蹴而就完成的,我們必須與專家建立聯繫,反覆溝通後完成。需求分析必須遵從的是一定的科學方法,而不是盲目的大上快上。

我的最後一個故事可能典型到幾乎每個人都曾經遇到過。我們的項目從需求分析到設計、開發、測試都十分順利。但到了項目進行的後期,快到達最後期限時,我們將我們的開發成果提交給客戶看,客戶卻對開發結果不滿意,提出了一大堆修改,而且這些修改工作量還不小。怎麼辦呢?加班、趕工,測試時間被最大限度壓縮。最後項目倒是如期上線了,但大家疲憊不堪,並且上線以後才發現許多的BUG。需求分析不是一蹴而就的,它應當貫穿整個開發週期,不斷的分析確認的過程。以上這個事例,如果我們提早將開發成果給客戶看,提早解決問題,後面的情況就將不再發生。這就是敏捷開發倡導的需求反饋。敏捷開發認爲,需求分析階段不可能解決所有的需求問題,因此在設計、開發、測試,直到最終交付客戶,這整個過程都應當不停地用開發的成果與客戶交流,及時獲得反饋。只有這樣才能及時糾正需求理解的偏差,保證項目的成功。

以上的故事各有各自的不幸,各自都在不同的開發環節出現了問題。但經過深入的分析,各自的問題最終都歸結爲需求分析出現了問題。爲了使我們今後的軟件項目不會重蹈覆轍,似乎真的有必要討論一下我們應該怎樣做需求分析。

我們應當怎樣做需求調研:初識

很多需求分析的工作是從需求調研開始的,我們就從這裏說起吧。需求調研是需求分析最重要的一環,也最集中地體現了需求分析的特點——既是一份體力活兒,更是一份技術活兒。它既要求我們具有一種理解能力、設計能力,更要求我們具有一種與人交往、溝通的能力。

在一個陽光明媚的下午,項目經理帶領着項目組成員,參加了客戶組織的見面會,一個新的軟件研發項目就這樣開始了。雙方在一種友好的氣氛中進行,相互寒暄,介紹與會人員,拉拉家常。逐漸地,會議開始進入了正題。初次接觸客戶,對於項目團隊意義重大。對方對你印象的好壞,今後如何與你交往,都在這個階段被確定下來。然而,在客戶至上的今天,與客戶保持適當的謙卑是有必要的,但過於的謙卑卻常常給項目日後的進程帶來風險。爲什麼這麼說呢?過於的謙卑,處處都是諾諾諾,客戶說什麼就是什麼,就會使客戶變得非常強勢。這樣的結果就是,客戶提出了許多變態的、不太現實的、不合理的需求,而我們呢卻是一味地服從,客戶說什麼就是什麼。最後我們做得很累,結果卻不能讓客戶滿意。

正確的做法是,我們對客戶提出的需求進行深入理解以後,運用我們專業知識,提出比客戶的原始需求更加合理、可操作的解決方案,讓客戶感覺你說的正是他們想要的。如果能夠這樣,客戶不僅能夠欣然接收你提出的方案,而且會感覺你非常專業,你在客戶心目中的形象也會無形中提高,使你有更多的機會提出有利於開發的可行方案,降低開發的風險。這毫無疑問會形成一個良性循環,但要做到這一點並不容易,毫無疑問,在與客戶接觸初期的表現起到了極其關鍵的作用。

人與人交往,往往在接觸的初期就決定了相互的行爲方式,與客戶交往也是一樣。起初的唯唯諾諾,客戶說啥就是啥,必然造成客戶不再關注你的意見,對你發號施令就可以了。相反,起初展現出一位技術專家的姿態,能大方而得體地提出自己的意見,會使客戶重視你的意見,甚至主動徵求你的意見。這一方面要求我們對自己要有足夠的自信,另一方面也要有循循善誘的表達能力。如果我們做到了這些,就會客戶心目中形成一種威信,使項目向着一種良性的方向前進。

同時,這樣的會議又是一個項目啓動會議。客戶方領導要在會議上傳達給與會代表一個清晰的信號,那就是與會代表今後要積極配合我們完成今後的工作。這時候,我們要弄清,客戶方有哪些角色,誰是這些角色的需求提出者與決策者。這是什麼意思呢?在軟件項目中,特別是管理型軟件項目中,客戶都代表的是一個羣體,而不是個人。他們代表的可能是一個單位、一個集團,甚至是一系列組織機構。在這樣一個羣體中,他們按照職能被劃分成了不同的角色。拿一個單位來說,橫向可能劃分成不同的部門,財務部、銷售部、採購部、生產部••••••不同的部門,由於業務的不同,對軟件的需求自然是不同的,因此我們在進行需求調研的時候,什麼部門的需求就應當跟什麼部門談。同時,縱向又可以劃分爲多個層次,如高層領導、中層領導與基層人員,理解這些方面格外重要:

1. 高層領導
高層領導關心的是宏觀的目標,因此軟件研發目標、宏觀統計報表、決策支持功能,都應當與高層領導談。他們關係的都是宏觀的問題,因此不要與他們談那些細枝末節;

2. 中層領導
中層領導關心的是具體的效益,即軟件給各個部門信息化管理方面帶來的效益,因此,中層領導是各項業務流程、功能模塊的需求決策者。他們關心功能的定義、業務流轉的銜接、查詢報表的設計,但不太關心一些具體的操作,以及一些具體業務流程的細節;

3. 基層人員
基層人員是每一項業務流程的操作者,也是軟件今後真正的使用者。他們是真正瞭解你所要開發的軟件的業務需求的領域專家,是你進行需求調研的重點對象。但是,基層人員往往受到自身視野的侷限,可能只清楚自己工作涉及的十分狹小的一個範圍,因此我們需要努力尋找那些業務涉及面廣,經驗豐富,又有一定大局觀的真正的專家。另外,他們就是軟件今後真正的使用者,讓他們參加,會讓他們成爲今後軟件推行的忠實支持者,對其他操作人員的指導者,益處多多。而他們關心的則是每項操作的細節。

劃分清楚角色,弄清楚每個角色的需求提出者與決策者,就是爲了在今後的需求調研中找對正確的人,使今後的調研工作事半功倍。另外,如果客戶方是一個集團、一個多組織機構的政府機關、事業單位,需求的多元化問題必須引起我們的足夠重視。什麼是多元化問題呢?比如同樣一個業務操作,在同一級別的A單位是這樣操作的,而在B單位卻是那樣操作的。需求的多元化往往會給今後的軟件開發帶來巨大挑戰。因此,我們要在需求調研階段降低軟件的多元化需求。要解決這樣的問題,首先應當從高層領導着手,提出規範化管理的口號。同時,在進行需求調研時,儘可能地召集各個單位的代表在一起開會討論。同時,應當有高層領導,或者指定一個負責人,在出現分歧的時候最終拍板決策。這些都需要在項目啓動的時候事先規劃好。

最後,與客戶方領導制訂出軟件目標,是相當重要但常常被我們忽視的一個步驟。軟件信息化管理不是包治百病的神藥。很多項目的失敗都歸因與項目目標不明確造成的項目範圍的失控。因此,這時討論項目目標,既重要又適時。

也許在此之前我們已經做足了功課,對業務需求進行了一番詳細的整理,有了一大堆疑問急需解答。但是,在這時,不是解答具體問題的地方,這是我們常常會犯的一個毛病。在這樣一個會議上,我們應當詢問客戶方領導對這個項目的期望,渴望達到的項目預期,而我們應當描述的,是對達到這些預期的整體解決方案,凡此等等。

俗話說:萬事開頭難。如果你在項目開始的時候總感覺千頭萬緒不知如何着手,在這裏我給大家的三點建議:1)樹立良好的職業威信;2)進行詳細角色分析,將與會各方代表對號入座;3)從宏觀上制訂目標與方案。隨後的工作,就是與各方代碼建立聯繫,逐一拜訪他們,將需求調研工作一步一步進行下去。


我們應當怎樣做需求調研:拜訪

項目組經過一番努力,獲得了一些初步的成果。首先是給客戶留下了一個良好的印象,這是一個開端,但要在他們心目中樹立自己的職業威信還要看你今後的表現。同時,我們與客戶一起爲項目制訂了短期與長期目標。不要小看了這些目標,它們就是我們的尚方寶劍。正是因爲有了它,今後項目中的有關各方就應當協助實現這個目標。我們應當清晰地向客戶表達這樣一個意思,要完成這樣的目標,不是某一方的努力,而是雙方共同努力的結果。這也是客戶方召開這樣一個項目啓動會議的重要意義。最後一個成果,也是最重要的成果,就是與各種角色、各個類型的客戶建立了聯繫。下面,我們將一個一個去拜訪他們,展開我們的需求調研。

與西方人不同,中國人做事往往比較重視感情,這是與中國數千年的文化分不開的。讓我們來聽聽一位金牌銷售員是怎麼做生意的:“我跟客戶頭幾次見面,絕對不提生意的事,玩,就是玩。吃飯啦,唱卡拉OK啦,打球啦••••••先建立關係,關係好了再慢慢提生意的事兒。”這說得比較誇張,畢竟他是在做銷售,但至少傳達出一個概念,那就是做事先培養感情,感情培養起來纔好慢慢做事,需求調研也是一樣。

需求調研不是一蹴而就的事情,是一件持續數月甚至數年的工作(假如項目還有後期維護)。在這漫長的時間裏,我們需要依靠客戶這個羣體的幫助,一步一步掌握真實可靠的業務需求。不僅如此,技術這東西總有不如意甚至實現不了的地方,我們需要客戶的理解與包容,這都需要有良好的客戶關係。按照現在的軟件運作理念,軟件項目已經不是一錘子的買賣,而是長期的、持續不斷的提供服務。按照這樣的理念,軟件供應商與客戶建立的是長期共贏的戰略協作關係,這更需要我們與客戶建立長期友好的關係。

儘管如此,我們也不能總是期望客戶中的所有人都能與我們合作,很多項目都不可避免地存在阻礙項目開展的人。如很多ERP項目會損害採購和銷售人員的利益,因爲信息化的管理斷了他們的財路;很多企業管理軟件會遭到來自基層操作人員的抵制,因爲它會給基層操作人員帶來更多的工作量負擔。有一次,我們給一個集團開發一套軟件,當我們下到基層單位時,才發現,一些基層單位已經有了相應的管理軟件。我們的軟件成功上線,必然就意味着這些基層單位的管理軟件壽終正寢,這必然影響到基層信息化管理專員的利益和政績。

分析一個客戶人羣的關係,就是在分析這個人羣中,誰有意願支持我們,而誰卻在自覺不自覺地阻礙我們。那些通過這個項目可以提高政績,提高自身價值的人,都是我們可以爭取的盟友。他們是我們最可以依賴的人,我們一定要與他們站在一起,榮辱與共,建立戰略合作伙伴關係。

另一種人,即使軟件獲得了成功,也與他沒有太多關係,但你與他相處得好,卻可以給予你巨大的幫助,這種人是我們需要拼命爭取的人。所謂領域專家,他可以給你多講點兒,但隨便打發你,對他也沒太大影響。報着謙虛謹慎、相互尊重的態度,大方地與他們交往。當他們幫助我們以後,真誠地予以感謝。這是我總結出來的,與他們交往的準則。

最後,就是那些對我們懷有敵意的人。儘管有敵意,但我們能夠坦蕩的,敞開心扉的與他們交往。雖然不能奢望太多,但拿出誠意去爭取他們,也還是有機會化干戈爲玉帛、化敵爲友。如果能夠那樣,那是再好不過了。

經過一番交往,我們將逐漸在客戶中結識一批可以幫助我們的人。今後一段日子裏,我們將依靠他們去學習和認識業務知識,收集業務需求,爲日後的軟件研發提供素材。

我們應當怎樣做需求調研:研討會

經過一番努力,我們終於在客戶中找到了一批人,可以解答困擾我們多時的業務問題了,真是不容易呀。但是,如何以合適的時間、合適的地點、通過合適的形式與客戶研討業務需求,是擺在項目經理面前的一道難題。在我所經歷的項目中,業務研討會沒有一個是相同的。


我曾經做過一個政府機關的項目,在這個項目中,從總局到省、地市、區縣,形成了一個多組織機構的管理系統。雖然全國管理流程大體相同,但各地因各地實際情況的不同、領導管理思路和政策理解的不同,管理模式在許多細節上存在着差異,也就是說,這個項目存在着需求個性化的問題。在項目進行之初,客戶方領導提前意識到這方面的問題,因此在組織需求研討時,分別從各個省市抽調業務人員,集中在一起進行研討。同時,在研討時,根據與會人員的業務特點,將他們分成若干個業務組,分別對某個相對獨立的業務模塊的需求進行研討。採用這樣的組織形式,各地的業務差異在會上都會被提出來。一些地區不合理的管理模式,一經提出,就會得到其它地區業務人員的糾正,進而避免了不合理需求的提出。當然業務人員之間也會出現意見分歧。在會議啓動之時,高層領導就明確提出了必須形成全國統一版本。因此,一旦出現分歧時,業務人員就會通過激烈辯論、各抒己見,進而形成統一意見。如果分歧雙方誰都說服不了誰,業務組指定的組長則拍板採用哪個方案。如果他不能做出決定,就立即反映到總局領導那裏當場做出決定。採用這種集中式的研討,可以使問題的處理變得高效而及時。當然,也會因地區化差異而出現多個方案,每個方案都是合理的,我們必須在軟件中分別對其進行處理的情況。出現這種情況時,至少我們很容易理清楚有幾種情況,有沒有可以合併的地方,使得差異最小化,最終在軟件維護中體現出來,讓客戶自己去選擇自己的管理模式。

另外,將業務人員劃分爲多個業務組也是一項比較成功的經驗。由於業務人員自身的侷限,不可能對所有業務領域的細節全面掌握,往往總是有自己熟悉的部分,也有自己不熟悉的部分。劃分業務組,可以讓業務人員分別在自己最熟悉的業務範圍內參與討論,可以有效提高業務討論的質量。同時,一個管理系統涉及的業務是複雜而系統的,如果劃分成多個模塊並行地進行業務討論,也可以大大提高業務研討的工作效率。這個項目採用這種方式,使這個項目在運行數年後依然能保持統一的版本,而不至於形成一個一個的地方版本。統一的版本使得軟件的升級維護成本大大降低,使項目進入良性的進化、完善的循環中。

以上講的是一種集中式的業務研討形式。採用這是形式固然好處多多,但並非所有軟件項目都能夠採用這種模式。我參與過的另一個項目就沒有如此幸運了。在這個項目中,雖然也是多組織機構管理系統,但總公司對各分子公司的管理是鬆散的,所以很難組織各地的業務代表集中在一起討論,甚至不能要求各分子公司採用統一的管理模式。企業信息化的目的就是要建立統一的、規範化的管理形式,它本身就是一場企業管理的變革。我們的軟件,如果不能規範各分支機構的管理,抑制個性化差異,而是照貓畫虎地一家一家爲分子公司做軟件,不僅我們的成本是巨大的,客戶的信息化管理效果也不能發揮出來,而且爲日後的運行維護帶來巨大的隱患。毫無疑問,它是我們做管理軟件的一個雷區,我們必須小心應對。

起先,總公司領導帶着我們一家一家地去分子公司開需求研討會。每個需求研討會,我們都要着力注意各個單位管理模式的差異。當業務代表在描述自己業務流程的時候,我們常常提示業務代表,×××公司是這樣管理的。這時候,業務代表會思考,採用×××公司的管理模式是否會更好,或者採用×××公司的管理模式行不行。如果他提出×××公司的管理模式可能會出現什麼什麼問題時,我們也會着力記錄下來,下次再和×××公司討論,他們是不是會出現這些問題。

採用這種分散式的業務研討形式,讓我們作爲外人來規範客戶的管理模式,常常會有這樣那樣的不便,但這也是我們可能面對得最多的需求研討形式。在這樣的形式中,尋找一個典型範例也許可以算是一種最佳實踐。當我們面對管理鬆散的多組織機構時,尋找一個管理規範、對我們的支持度高的分支機構,首先將他們的信息化系統建立起來,產生預期的效益,這就樹立了一個範例。它的成功就會爲其它分支機構帶來一種精神動力和成功案例,照着做肯定不會錯。這樣就可以更容易地說服其它分支機構,摒棄現有的管理模式而朝着規範化管理邁進。

業務研討形式比較容易出現的另一個問題,就是將各個方面的業務代表拉過來開大會。在大會上,你說你的,我說我的,雜亂無章,一些重要的需求被不經意地漏掉。遇上這樣的情形,項目經理應當有清醒的認識,我們需要再下來開小會。銷售部門的需求跟銷售部門談,採購部門的需求跟採購部門談••••••既然是小會,每次談的時候人不在多,在精,參會的業務人員對自己的業務瞭解精細而全面。這樣的會議,通常有一至三個業務人員,和一個負責人(負責拍板)參加。會議之後,我們最好詢問與會人員的聯繫方式,便於日後建立長期的聯繫,畢竟業務需求不是一蹴而就的事情。同時,如果我們今後採用的是迭代式開發,他們也就成爲了我們業務驗證的客戶代表。

業務研討會是重要的,但同時又是靈活的,沒有一個定式,甚至有時都不能稱之爲會議。項目經理需要根據實際情況,合理地與客戶組織研討會。但不論怎樣組織,必須注意兩點:有效抑制個性化差異、分模塊組織專項研討會。


我們應當怎樣做需求調研:需求研討

前面我們探討了業務研討會應當怎樣組織,下面我們再具體討論一下我們應當怎樣與客戶討論業務需求。如果說組織業務研討會是項目經理的功底,那麼討論業務需求就是需求分析人員的功底。

以往我們常常認爲,需求分析是一件最簡單的事情。客戶說他們需要做一個什麼軟件,有些什麼功能,我們照着做就可以了,所謂的需求分析員就是需求的記錄員。我要說,這是一個極大的錯誤,許多失敗的軟件項目,或者說軟件項目中的需求問題,大多都源於此。經過人們多年的研究發現,在需求分析過程中,客戶存在的最大問題就是提不出正確的需求,這表現爲幾種形式:

1. 由於對軟件不瞭解,客戶提不出需求,不知道軟件最終會做成什麼樣子。這類客戶在需求討論過程中,往往只能描述目前自己手工管理的方式是怎樣的,不知道計算機會怎樣管理。

2. 能提出一些業務需求,但當軟件做出來擺在自己面前時,需求就變了。這類客戶,他們能熟練使用電腦,對信息化管理是清楚的。他們提出的業務需求從整體上應當是八九不離十的。但是,由於沒有實物,在軟件中的一些具體操作並沒有完全想清楚。因此,當軟件真正做出來擺在自己面前時,甚至經過一系列流程操作以後,會對一些操作提出變更需求。他們正如那句經典的話說的:“I have changed when it saw it.”

3. 能非常詳細地提出業務需求,甚至有時候該怎麼做的提出來了。這類客戶,參與過很多軟件信息化建設,甚至有些還是軟件開發的半專業人士。但是他們提出的業務需求過於具體,甚至怎樣實現都說出來了,但這些有時候不是最佳設計方案、可能在技術上難於實現,甚至有些就是過於理想化而不可實現。

因此,我在進行需求研討的時候,首先跟客戶探討的不是軟件功能,而是客戶現有的業務知識,用專業的話叫“業務領域分析”。客戶現有的業務流程是什麼樣的,都有些什麼操作?客戶在業務中都有些什麼事物,什麼專用名詞,都是怎樣定義的,相互之間的關係是什麼?客戶在每一項操作中的目的是什麼,爲什麼要這樣做,他們製作的手工報表都說明了什麼問題?後面我會更加詳細地描述怎麼進行業務領域分析。

在認識了客戶的業務領域之後,我們才能去分析他們提出的所有原始需求。他們爲什麼要提出這項需求,提這項需求的目的是什麼?只有經過這樣的分析,我們才能深刻地理解需求,進而運用我們的專業知識,提出更加合理的技術方案。但非常遺憾,我們在需求分析中常常不是這樣做的,甚至當軟件都開發出來了,需求分析人員都說不出客戶爲什麼要提出這個需求,更談不上了解業務操作流程。一句經典的話是:“客戶讓我們這樣做的。”

總之,我們做需求分析,眼界不能僅僅停留在軟件本身,應當更開闊一些,應當擴展到跟這個業務有關的那些領域知識中。

當然,另一個極端就是爲了開發軟件,無限地擴大學習領域知識的範圍。爲了開發財務軟件去考會計師,爲了開發稅務軟件去學習稅法等等。開發軟件不是讓我們成爲這個領域的專家。我們學習領域知識是爲了更好地理解和開發軟件,是學習與這個軟件有關的領域知識,而不是成爲一個專家。

在客戶提出的所有原始需求中那些與業務實現有關的需求都是無效的需求,它們僅僅只能作爲我們的一個參考。什麼是與業務實現有關的需求呢?比如要求做成什麼界面,數據要求怎樣處理,等等。爲什麼是無效的呢?因爲客戶畢竟是非專業,我們應當有這種自信,在理解客戶真實意圖以後,能夠提出比客戶更優的解決方案。

還有一些是技術難於實現或者根本就無法實現的需求,我們應當耐心地說服和引導客戶,並給他提出一個更加合理的方案。注意最後一句話:“給他提出一個更加合理的方案”。蒼白的拒絕客戶往往會讓客戶產生牴觸情緒,但當我們提出一個更加合理的方案時,客戶往往會欣然接受,當然這是在我們對客戶提出的業務需求的真實意圖進行深入分析之後。認識到這一點非常重要,爲了更加清楚地說明這一點,我舉一個我的例子吧。有一次我給客戶做一個價格管理系統時,客戶提出要做一個動態報表的需求。這個動態報表要求能讓客戶從無到有,完全自由的定製自己的報表。毫無疑問,這是一個典型的不切實際的業務需求。接到這個需求以後,我們將它作爲一個疑問,在整個需求調研過程中着力進行了考察,明白了客戶爲什麼提出這樣的需求。當客戶在向他們的客戶報價時,他們的客戶在各個方面都要求他們報出價格細目,而且不同的客戶要求他們報的價格細目格式還不一樣。但經過仔細分析,發現他們面對的客戶就是固定的幾家,而這幾家的要求的報表雖然格式不盡相同,但其數據項大體是相同的。最後,我們給客戶提出兩個方案,一個是按照客戶所說的動態報表,但要求客戶在製作報表時必須能夠詳細設計報表中數據項的來源、項目的類型,以及繪製報表格式,讓他們意識到,即使做出來,作爲非專業的他們也是很難自己完成的。同時,我們提出另一個方案:我們爲客戶準備好他們需要填寫的各種客戶報表所需的所有數據項,讓他們自由刪減。同時,爲他們的不同客戶提供各自相應的報表模板,這些模板可以在少量的範圍內進行修改,以此滿足他們的客戶的不同需要。當客戶拿到這樣的方案,既能滿足他們自己的需要,還操作簡便、易懂、不費事,當然就欣然接收啦。

因此,需求分析不是一種簡單的你說我記的收集活動,而是在大量業務分析與技術可行性分析基礎上的分析活動。只有建立在這種分析基礎上的軟件研發,才能保證需求的正確與變更的可控。


我們應當怎樣做需求調研:迭代


前面我一直在反覆強調這樣一個觀點,需求分析不是一蹴而就的,是一個反覆迭代的過程。它將從第一次需求分析開始,一直持續到整個項目生命週期。爲什麼這樣說呢?讓我們一起來分析分析。

在第一次的需求分析階段,我們在一段時期內需要與客戶進行反覆地討論,這個過程往往是這樣一個反覆循環的過程:需求捕獲->需求整理->需求驗證->再需求捕獲••••••

需求捕獲,就是我們與客戶在一起開研討會,討論需求的活動。客戶可能會描述他們的業務流程,這時我們在紙上繪製簡單的流程草圖,及時地記錄下來;客戶在描述業務的同時,可能會反覆提到一些業務名詞,詳細詢問這些名詞的含義,以及它們與其它名詞的關係,用類圖或者對象圖繪製簡單的草圖;客戶在描述業務的同時,還會提出今後的軟件希望實現的功能,如能夠展示某個報表、能夠導出文件,以需求列表的形式記錄下來。一個功能,在需求列表中會有多個需求,而每個需求應當能夠用1、2句話,在20個字以內就可以描述清楚。需求列表是客戶提出的最最原始的需求,他不摻雜任何分析設計,是我們的每項功能必須實現的內容。需求列表是需求驗證以及日後的用戶驗收測試的依據,不論我們今後如何分析和設計這些功能,都要能如實地實現這個列表中提出的需求。(需求列表應當如何編寫,將在後面的章節詳細描述。)

需求整理,就是在需求研討會後,需求分析人員對研討內容的分析和整理的過程。首先,需求分析人員應當通過用例模型,劃分整個系統的功能模塊,以及各個模塊的業務流程。用例模型分析是一個由粗到細的過程,這樣一個過程也是符合人類認識世界的思維習慣的一個過程。最先,我們應當對整個系統繪製用例圖,設計用例場景,並依次對這些用例進行用例描述、流程分析、角色分析等分析過程。當然,在整體用例分析的同時,我們還應當進行一個整體的角色分析,繪製一個角色分析圖,進行一個流程分析,繪製一個流程分析圖(可以是傳統的流程圖、UML中的行動圖,甚至一個簡單的示意圖,等等)。

然後,我們再在整體用例圖的基礎上,依次對每個用例繪製用例圖。每個用例圖中,會更細緻地劃分出多個用例,並依次進行用例描述、流程分析、角色分析等分析工作。如此這般地不斷細化,直到我們認爲需求已經描述清楚爲止。

在一個系統中,用例需要細化幾次,是由這個用例的業務複雜程度決定的。對於一個簡單的用例,只需要細化一次就夠了;而對於比較複雜的用例,則需要細化2~3次,甚至更多。

用例分析的過程,之所以稱之爲分析,它摻入了很多需求分析人員對業務的理解與設計:模塊如何劃分、流程如何設計、業務如何轉換,等等。用例分析,還需要讓需求分析員與架構師、設計師等技術人員共同協作來完成,因爲用例分析還包含對業務需求的技術可行性分析。只有一份可行的需求分析,才能爲後續的設計開發掃清障礙,有效降低項目風險。最後,需求分析員應當將需求列表中的內容,逐一地與用例進行覈對,以避免分析人員忽略用戶的某項業務需求。(後面將詳細描述用例模型的搭建過程。)

在用例分析的同時,需求分析人員還需要對業務中的相關事物,製作領域模型。領域模型,是對用戶業務領域中相關事物、相互關係、相互行爲操作的描述,它是以對象圖和類圖的形式表達的。需求人員對領域模型的分析,對業務理解的深度,對日後軟件的設計,以及軟件的功能擴展、升級演化,都起到了至關重要的作用。(後面將更加詳細地講述領域模型。)

最後,當我們完成了一系列的分析整理並形成文檔以後,應當對及時地與客戶進行反饋,確認我們的理解是否正確,也就是需求驗證工作。需求驗證工作應當貫穿整個研發週期,並且在不同時期表現出不同的形式。首先,在需求分析階段,需求驗證工作表現爲對需求理解是否正確的信息反饋。需求分析人員與客戶再次坐在一起,一項一項描述我們對需求的整理和理解,客戶則時不時地對一些問題進行糾正,或者更加深入地加以描述。我們則認真地記錄,回來整理,並等待下一次的驗證。在需求分析後期,我們還可以製作一些簡單的原型,更加形象地描述我們對需求的理解,會使我們與客戶的溝通更加順暢。隨後的設計開發階段,我們則應當以迭代開發的形式進行。每開發完一個迭代週期,將開發的成果與客戶反饋。這樣做的結果是,客戶可以及時地提出我們對需求理解的偏差,或者及時提出對我們設計不滿意的地方,使我們存在的問題得到及時地發現與解決。問題及時的解決,使我們修復問題的代價得以降至最小。之後,當開發進入到驗收測試階段,我們則是與客戶一道,一項一項地驗證我們的軟件是否滿足需求列表中要求的業務需求。最後,當軟件迎來下一次升級開發時,我們將開啓另一次輪迴。

因此,需求分析就是按照這樣的過程,每次多理解一些,再多理解一些,更多理解一些,逐漸深入的過程。每深入一步,我們的軟件就更接近客戶的滿意。


我們應當怎樣做需求調研:需求捕獲

前面我們討論了,需求分析工作是一個迭代的過程:需求捕獲->需求整理->需求驗證->再需求捕獲······需求捕獲是這個迭代過程的開始,也是整個需求分析工作中最重要的部分。沒有捕獲哪來後面的整理與驗證工作?但是,非常遺憾,按照我以往的經驗,需求捕獲是我們最薄弱的環節。前面我提到的許許多多項目開發的問題都可以歸結爲需求分析的問題,而許許多多需求分析的問題又都可以歸結爲需求捕獲不完整的問題。需求捕獲是整個需求分析工作中最難把握的一個部分,它不僅僅是一個技術的問題,還涉及到人際交往、溝通、知識理解,以及心理學等一系列問題。但更讓我感到遺憾的是,在我讀過的許許多多關於需求分析的書籍中,討論需求分析與建模的書很多,但討論需求捕獲的書籍卻寥寥無幾。確實,要討論這部分內容,真的已經遠遠超出了軟件開發這個知識領域。

那麼,在軟件需求捕獲過程中,最根本、最容易犯錯的問題是什麼呢?我認爲是一個態度的問題,是採用主動態度去捕獲需求,還是採用被動的態度去捕獲需求。如果需求分析人員總是諾諾諾,客戶說什麼,我們就記什麼。客戶處於非常強勢的地位,給我們提出了非常多變態、技術難於實現的需求,而我們的需求分析人員卻成爲記錄員,埋頭記錄客戶說的每一句話,不加分析地就直接扔給了開發人員。這就是採用被動的態度去捕獲業務需求的方式。毫無疑問,這樣的需求分析必然將給項目開發的後期帶來巨大的風險。

爲什麼會出現這樣的情況呢?經過深入分析我們會發現,從客戶嘴中說出來的需求,只是整個軟件需求中的冰山一角,還有兩類需求需要我們自己去挖掘:客戶嘴中沒有說出來的需求,和客戶壓根兒就沒有想到的需求。

什麼是客戶嘴中沒有說出來的需求,並不是客戶故意賣弄官子不願說出來,而是在客戶所在業務領域已經約定俗稱,在他們看來已經是天經地義,根本就不用說出來的業務規則。然而,作爲剛剛涉足該領域的需求人員,他們是不瞭解這些規則的。如果採用被動的方式去僅僅記錄客戶說出來的需求,毫無疑問會遺失這部分需求,這就是爲什麼直到項目後期,軟件被研發出來即將交付使用,客戶才提出說這不是我想要的軟件,並提出大量變更需求的原因。這時,我們常常問客戶,你們爲什麼不早說呢?而客戶卻十分委屈,這麼簡單的道理還需要我說出來嗎?

舉例說明吧:在我從事的稅務行業中,對納稅人徵收的稅種包括增值稅、企業所得稅。增值稅通常是按月徵收的,而企業所得稅是按季或者按年徵收的。就拿增值稅來說吧,稅款所屬期是開票日期的上個月,爲什麼呢?納稅人往往是在上個月產生銷售收入,然後在下個月完成申報和繳納稅款。這些知識對於稅務人員來說是太基本的常識了,所以在他們看來就是天經地義而不需要說出來的業務規則。但作爲軟件開發人員的我們卻常常因爲不知道而將業務弄錯。

如何破解這樣的問題呢?那就是要求我們在需求分析的整個過程,不斷進行業務領域知識的學習。在我做需求訪談的初期,我往往不是跟客戶談需求,而是先跟客戶談業務。你們是怎樣操作的?都經過些什麼流程?誰來完成這些操作的?爲什麼這樣操作?注意,在所有這些問題中,最後一個問題是最重要的。客戶業務領域中的所有操作、所有流程都是有它存在的意義的,它體現了其內部的原因與作用。多問爲什麼,可以讓我們深入地理解這些領域知識,站在客戶的視角去思考問題,進而深入地理解客戶爲什麼要提出他們的那些業務需求。當一個需求分析員能達到這樣的水平,客戶嘴中沒有說出來的需求就會被源源不斷地被發掘出來,最終做出來的需求分析纔是完整的、準確的。

另一種就是客戶壓根兒沒有想到的需求。也許你會提出這樣的疑問,客戶壓根兒沒有想到的需求我們還提出來做什麼?這種壓根兒沒有想到的,實際是在業務需求階段壓根兒沒有想到的,並不代表最終都沒有想到。很多開發人員總在埋怨,說客戶需求總是在軟件項目的後期改來改去,爲什麼?客戶並不是軟件研發領域的專業人員。在業務需求階段,由於沒有可以展示和操作的實物,客戶總是在空對空的憑空想象今後的軟件應當做成什麼樣子。這就註定了客戶會有很多自己壓根兒沒有想到的需求。那麼爲什麼他們會在軟件研發的後期提出來呢?因爲軟件研發的後期,客戶能拿到那些研發成果的實物,去操作,可以看到。這時候,很多他們起初沒有想到的需求就會源源不斷地被提出來。但這時候,我們作爲研發人員會很傷,我們付出的代價會很大。所以,以被動的態度去完成需求分析工作,必然會給項目研發帶來巨大的風險。

如何解決這樣的問題呢?首先,在需求分析階段,雖然客戶壓根兒沒有想到,但需求分析人員是軟件研發領域的專業人員,他們應當在深入理解業務領域與需求的基礎上,通過分析提前發現這些需求。作爲需求分析人員,他們應當站在客戶的角度去思考,我們的軟件應當設計成什麼樣子,每個需求的真實意圖是什麼。站在這個基礎上,再運用專業知識去整理、分析與設計。我前面談到,客戶描述的最原始的需求是編寫在需求列表中的,而經過需求分析人員的整理、分析與設計,經過用例分析、領域建模,最終形成產品需求說明書(或稱爲產品規格說明書)。從需求列表到產品需求說明書,這之間要經過一段長長的路,這段路就是我們的分析與設計,而不是簡單的記錄與編寫文檔。只有經過這樣的過程,最後得到的纔是高質量的需求分析,纔能有效地指導軟件研發,避免項目的風險。所以說,好的需求分析人員就是軟件項目的司命,掌握着項目的生死。

我們再換一個角度來分析,客戶之所以提不出需求,關鍵就在於他們沒有可以展示和操作的實物,總是在空對空的憑空想象今後的軟件應當做成什麼樣子。我們能否改變這樣一種現狀呢?於是,迭代式的需求分析與開發就出現了。我們先用最短的時間先做一個可以展示和操作的原型給客戶看,讓客戶提一些意見。然後我們再在這個原型的基礎上再多做一些,再給客戶看。我們就這樣一步一步推進,直到最終項目研發結束。採用這樣的方式,最適合那些客戶在項目初期提不出什麼需求,也沒用合適的參照物來進行需求分析的軟件項目,特別是那些數據分析與決策類的軟件項目。

接下來,我們再回到那些從客戶嘴裏說出的需求。在需求分析人員中,比較普遍的一個看法就是,只要是從客戶嘴裏說出來的,就一定是對的,我們必須照着做的,這種看法是不正確的。因爲客戶在軟件開發方面是非專業的,所以他們在提出需求的時候往往會考慮不夠周全。有一次,客戶在提出來一系列業務操作以後,最後提出了一個統計報表的功能。這個統計報表是從前面這一系統操作數據中統計出來的,因此我們就對這些業務操作及其結果數據進行了一個詳細的分析,最後發現根據這些數據統計出來的數據存在很多的問題,甚至可能出現相互矛盾的地方。隨後我們與客戶就這些問題進行了深入地探討,最終客戶不得不承認,他當初在設計這個報表的時候考慮不周全。在提出問題的同時,我們又提出了我們的解決方案,這是非常關鍵的。當我們提出我們的合理化建議以後,客戶欣然接受了。同時,客戶對我們這種非常專業的分析與處理過程大加讚賞,無形中也提高了我們在客戶心目中的威望。

不僅如此,客戶作爲一個羣體,客戶與客戶之前對同一問題也可能存在不同的看法,這特別突出地體現在那些多組織機構的管理系統中。因此,對於一些客戶非正式的場合提出的需求我們要仔細甄別。一個比較可行的方法就是,先在一些非正式的場合單獨跟客戶聊,產生第一手資料,最後將這些需求在比較正式的場合,如各部門參加的業務討論會、有用戶代表參加的需求評審會、需求定稿簽字確認會等等,以比較正式的形式討論和確定下來。

最後,我不得不說,企業信息化管理實質就是一次改革,是企業摒棄手工操作,向信息化建設邁進的一次改革。既然是改革,就必須要改變過去不合理的管理流程,向更加合理和高效的管理流程邁進。因此,我們的需求捕獲最初是源於企業現有的操作流程,但當我們深入理解了客戶現有的操作流程以後,應當有意識地發現那些不合理的部分,並最終提出更加合理、更適於信息化管理的流程。如果需求人員能上到這樣一個高度,我們的需求分析就進入了一個更加嶄新的層面(關於需求分析中的流程分析,我們還會在後面詳細探討)。


我們應當怎樣做需求分析:功能角色分析與用例圖

在我們進行一系列需求調研工作的同時,我們的需求分析工作也開始啓動了。需求調研與需求分析工作應當是相輔相伴共同進行的。每次參加完需求調研回到公司,我們就應當對需求調研的成果進行一次需求分析。當下一次開始進行需求調研時,我們應當首先將上次需求分析的結果與客戶進行確認,同時對需求分析中提出的疑問交給客戶予以解答。這就是一個需求捕獲->需求整理->需求驗證->再需求捕獲的過程。

但是,當我們經過一番忙碌,將需求中的第一手資料從調研現場捕獲回來以後,我們應當怎樣進行分析呢?不少團隊對此都比較迷茫,沒有一個統一和有效的方法,往往採用想到哪裏做到哪裏的方式。一些問題想到了就做了,沒有想到則忽略掉了。實際上,需求分析不應當是太公釣魚,而應當是拉網排查。任何一個疏忽都可能對項目研發帶來風險。因此,我們應當採用一套成熟而完整的分析方法,穩步而有序地完成這部分工作。不同類型的軟件項目其分析方法可能存在差異,但一般來說,信息化管理類軟件項目通常從這幾個方面着手分析:功能角色分析、業務流程分析與業務領域分析。

需求分析不是一項一蹴而就就可以完成的工作,它需要一個長期的過程,而這個過程是一個由粗到細的過程,它體現了人類認識事物的客觀規律。在需求分析的初期,我們對需求的認識往往是整體的、宏觀的,隨着分析工作的逐漸深入,一步步細化。按照這個思路,我們對需求的分析,首先應當從功能角色分析開始。所謂功能角色分析,就是從一個外部用戶的視角分析整個軟件系統能夠提供的功能,以及這些功能到底是提供給哪些角色使用。

對一個系統進行功能和角色方面的梳理和分析,可以採用的比較主流的方法之一就是繪製用例圖。用例圖是UML的4+1視圖中的一種,準確地說就是那個“+1”。用例圖是貫穿整個面向對象分析/設計(OOA/D)的核心視圖,它描述的是系統到底爲用戶提供了哪些功能,以及到底是哪些用戶在使用這些功能,是溝通用戶與技術人員的橋樑。運用用例視圖對業務需求進行分析、抽象、整理、提煉,進而形成抽象模型的過程稱之爲用例建模,而這個模型就是用例模型。

一般地,在一個用例圖中通常有三種元素:參與者(Actor)、用例(Use Case)與系統邊界(Boundary)。用例描述的是系統爲用戶提供的功能,也就是系統能爲用戶做什麼,通常被繪製成一個橢圓;參與者,我認爲稱爲角色更加合適,也就是系統爲哪些類型的用戶提供服務,他們都各自承擔哪些不同的職責,通常被繪製成一個小人兒;最後是系統邊界,也就是系統是對現實世界哪個範圍的內容進行的模擬,它涉及到軟件設計的工作範圍與工作量,通常被繪製成一個方框。但是,通常情況下系統邊界只是一個概念而不用真正繪製出來,因爲被繪製成用例的必然是系統內部的功能,被繪製成參與者的必然是系統外部事物。從這個意義上講,用例圖中的參與者不僅包括人,還包括那些外部系統和自動觸發器。根據這樣一個思路,我以往常常將外部系統和自動觸發器繪製成一個小人,這常常令客戶感到困惑。隨後我改變了思路,將外部系統和自動觸發器繪製成另一種表達形式——類元符號表示法,並在構造型上標註爲Actor。



上圖是一個考覈系統中一個子模塊的用例圖。圖中的用例就是這個系統提供給用戶的各項功能。注意,這裏僅僅是在羅列功能而不表示它們之間諸如流程調用等相互關係,這是一些初學者常常犯的毛病。參與者與用例通過實線關聯起來,代表的是一種使用關係。箭頭代表的是一種導航,即動作施與的方向。在這個用例圖中,普通用戶執行查詢操作,查詢系統提供的“預警監控單項查詢”、“預警監控彙總查詢”等查詢報表;每日自動觸發器觸發自動考覈功能,自動考覈功能從“稅收徵管系統”這樣一個外部系統中採集數據。

圖中考覈管理員和執法人員代表的是兩個完全不同的角色,但他們在這個圖中體現的是一些共有的特性,即對這堆報表的查詢,因此被繪製成繼承自普通用戶。繼承是參與者間唯一的關係,代表繼承者擁有被繼承者所有的功能與權限。除了參與者以外,用例與用例直接也存在着一些類型的關係,這我們在後面詳細講述。

在繪製用例圖時一個值得思考的細節是,用例是怎樣通過分析獲得的。這個問題,在一些客戶對信息化管理比較有經驗的項目中不存在問題,因爲在客戶提供給我們的需求文檔中就清晰地劃分出了一項一項的功能。這些功能可能會在日後的需求分析工作中有所調整,但它從整體上形成了一個雛形,成爲我們進行用例分析進而形成用例的依據。

但當我們面對的是一些對信息化管理沒有經驗的客戶,情況就有些不妙了。在這種情況下,通常客戶只能給我們一些管理目標、基本想法,其它的調研工作就需要我們自己去做了。這時,我給大家的建議是,首先從組織機構上劃分清楚系統涉及哪些部門、哪些科室,然後在這個基礎上劃分出來這些部門這各個科室的人員都扮演哪些不同職能的角色,以及完成哪些業務操作。系統中的一個功能,在一般情況下是組織機構中某個(或多個)角色,爲該機構某項業務流程完成的某個操作,並且這個操作應當有某個確定的結果(即產出物)。而這個功能就是我們需要提取出來的用例。雖然功能角色分析在整個需求分析過程中可能會隨着認識的深入而不斷調整,但分析過程大體是這樣進行的。

有人說,我們繪製的用例圖拿給客戶看不懂。這樣一個清晰明瞭的用例圖,輔之以我們對圖形的描述,客戶怎麼會看不懂呢?關鍵問題在於,我們沒有將用例圖的精髓弄明白,再加上出現一些常見問題,使得用例圖畫得不倫不類,客戶當然就看不明白了。現在我們看看用例繪製都有些什麼常見問題。

1. 沒有正確理解用例圖的視角。前面我反覆強調了,用例圖的視角是用戶,也就是說,站在用戶的角度來觀察的我們需要設計的系統。從這個視角,用戶看到的系統是什麼呢?當然是一項一項的功能,這些功能是客戶能夠理解的、具體的、對客戶存在價值的功能。從這個意義上說,那些技術性的功能不應當出現在這裏,或者應當描述爲用戶可以理解的文字,比如“自動考覈”。而那些應當繪製的用例,在取名時也應當站在用戶角度去取名。舉個簡單的例子,一個員工檔案信息系統,以往我們總愛將用例取名爲“添加員工信息”、“更新員工信息”、“刪除員工信息”,這就是典型的技術人員編寫的用例。“添加員工信息”對於用戶來講應當是做什麼呢——填寫新員工資料;“更新員工信息”對於用戶來講又是做什麼呢——更改員工資料;“刪除員工信息”又是什麼呢——員工註銷。不論是“填寫新員工資料”、“更改員工資料”,還是“員工註銷”,對於客戶都是日常工作中需要完成的操作,將用例命名爲這些名字必然爲用戶所理解。同時,每一個用例對於用戶來說應當是有價值的,也就是說,用戶使用這個功能是要完成一項操作,或獲得什麼信息。比如上圖的“自動考覈”會產生一批考覈結果,執行“預警監控單項查詢”可以獲得預警監控結果數據。

2. 圖形繪製雜亂無章。一個系統,特別是一個大型系統,提供給用戶的功能是繁雜的。如果你想將所有的功能,不管粗的細的,都試圖繪製在一個用例圖中,幾乎沒人看得懂。我們之所以將分析設計圖形化,是因爲圖形能給人形象立體的感官,使人立即就明白了其中的意思,但前提是,這個圖形是主題清晰的、形象生動的。因此,我們繪製用例圖要學會拆分,由粗到細地一個一個繪製。先整體的繪製,再劃分成各個模塊一個一個詳細繪製,再進一步細化。所以,描述一個系統應當有許許多多的用例圖。

3. 用例是一個場景。在現實世界中,我們常常面對的是一個個長而複雜的操作流程,但在軟件世界裏,我們要將它們拆分成一個個的用例,怎樣拆分?一個用例必須有一個場景,也就是時間相近、地點單一的一系列操作,並且這些操作最終應當有一個明確的結果。



如上所示這個用例圖,“申辯申請”就是過錯責任人填寫了一張申辯申請單,最終的結果是將申辯申請單提交給考覈管理員;“申辯受理”就是考覈管理員接收了過錯責任人的申辯申請單並予以受理,當然另一個結果是對其不予受理,該申請單被退回給過錯責任人。每個用例都有確定的場景,明確的目的和結果。

功能角色分析是對系統宏觀的、整體的需求分析,它用簡短的圖形繪製出了一個系統的整體輪廓。但僅僅進行功能角色分析是遠遠不夠的,我們還需要在它的基礎上做更加詳盡的分析。


我們應當怎樣做需求分析:業務流程分析

我們將從客戶調研現場拿回來的需求,經過一番功能角色分析,整個系統的整體脈絡與輪廓已經被勾畫出來。在這個過程中,我們首先將系統劃分成了幾個功能模塊(如果系統規模較大,還應先劃分爲幾個子系統,然後再劃分出各個功能模塊)。然後,我們爲每個功能模塊繪製用例圖。用例圖是站在用戶角度去觀察的系統,即系統爲用戶提供了哪些功能,這就是功能分析。同時,這些功能是爲哪些用戶服務的,這就是角色分析。我們繪製的用例圖應當能夠爲用戶所理解,這也是UML其中的一項核心思想——與客戶形成統一的、能夠相互理解的語言,這對於需求分析過程中與客戶的溝通是大有好處的。

但形成對系統的整體輪廓,對於軟件的需求分析來說是遠遠不夠的。許多軟件最終失敗的非常重要的原因就是對需求分析過於草率、浮於表面,而沒有深入細緻地去分析,往往到了項目後期才把需求搞懂,才發現真正的需求與起初的認識大相徑庭,才恍然大悟需求原來是這樣,而往往那時已經追悔莫及了。這樣的經歷相信你也有過吧。所以,我們一定要沉下氣來認真仔細地做需求分析,一定要做到位。

同樣,細化需求也需要一定的方法與思路。一般來說,我們可以有兩個方向細化需求:業務流程分析與業務領域分析。這裏,我們先談談業務流程分析吧。

如果我們現在做的需求分析是一個企業信息化管理系統,毫不疑問,我們的軟件系統就是在模擬企業已有的那些業務流程。在現實世界中,企業是按照怎樣的流程來管理,我們的軟件就應當去模擬這樣的流程。但是,我們的軟件不可能也不必要完全去模擬這樣的流程,在這個流程中的有些環節是應當由軟件去模擬的,但有些環節則是應當在系統之外,由人工去完成的。我們進行流程分析,就是要求分析哪些是系統之內的,哪些是系統之外的。

我曾經做過一個疑點信息庫系統。該系統模擬的原有業務流程是這樣的:高層紀檢方面的領導通過信訪、舉報、數據查詢分析等方式發現了一批問題,然後將這批問題製作成一套調查清冊,親自或者交由下級相關單位,下到基層去調查問題。直到調查工作完成以後,才從基層回到自己單位,填寫調查工作底稿,詳細描述調查情況,並結束調查工作。

首先,我們應當拋開軟件實現,對這樣一個流程進行梳理,形成這樣一個步驟:
1. 高層領導通過信訪、舉報、數據查詢分析等方式發現一批問題;
2. 將這批問題製作成一個調查清冊;
3. 自查或將清冊下派給下級去調查;
4. 下到基層執行調查;
5. 從基層回到自己的單位,填寫調查工作底稿,詳細描述調查情況,並結束調查工作。

然後,在對原始需求分析的基礎上,分析我們的軟件能做什麼事:
第一步:信訪和舉報雖然有自己的操作流程,但那些都在這個系統之外,在這個系統中僅僅只需錄入最後的結果。數據查詢分析過去只是業務人員在相關業務系統中根據自己的經驗執行各種查詢,現在則可以上一套數據採集和分析系統,提高數據分析的質量。
第二步:形成調查清冊,可以在系統中設計一個功能實現。
第三步:自查或下派,可以在系統中設計一個流程實現。
第四步:下到基層執行調查,由於網絡條件等因素的限制,業務人員不可能也不必要在系統中去完成調查,只需要執行一個標誌調查工作開始的操作,並打印或導出調查清冊,然後去基層調查。最終,這部分被設計成一個“開始實地核查”的操作,並提供打印導出功能。
第五步:調查人員從基層回到自己的單位都是系統外的事情,而填寫調查工作底稿,詳細描述調查情況,並結束調查工作,則是系統內的功能。最終,這部分被設計成一個“調查完結”功能,標誌調查工作結束,並提供工作底稿的填寫功能。

計算機信息化管理並不是萬能的,它並不能代替現實世界中的所有工作。因此,我們進行業務流程分析,就是要分析業務流程中哪些是需要信息化管理的,而哪些則不需要。信息化管理過細,無疑會加重基層業務人員的負擔(這也正是爲什麼許多基層業務人員會排斥信息化系統的原因),而適當的信息化管理則可以提高工作效率。試想一下,如果你工作中的每一個步驟都必須在計算機中操作一下,怎麼不讓人煩呢?而如果在工作中一旦需要先查一個什麼信息,或者需要計算一下,系統立即可以替你完成這些工作,或者那些過去基本靠吼的操作,現在立馬通過信息化就傳遞過去了,怎麼不讓人舒心呢?我們做信息化管理,不是要加重人的負擔,而應是降低人的負擔。以這樣的思路去進行流程分析才能設計出優秀的、人見人愛的管理系統出來。因此,我做需求分析,最喜歡下到基層去了解基層業務人員的需求,去分析怎樣設計流程才能提高他們的工作效率,而避免加重他們的負擔。“水能載舟,也能覆舟。”一套系統是否能順利推行下去,基層人員是否支持往往起到十分重要的作用。另外,業務流程分析的另一個重要的分析內容就是流程差異化分析。不同的領導有不同的思路,不同的單位有不同的情況。因此,我們在進行流程分析的時候,常常面臨流程差異化的問題。我們說企業信息化就是一次改革,這首先體現在業務流程的規範化操作,也就是消除這種流程差異。但不同的單位有不同的情況,這特別體現在不同地域和文化的不同,又常常造成這種流程差異不可避免。分與合,分治與一統,常常是一個都要兼顧的問題,非常微妙,我們要小心處理。在這個問題上你也許會問,使用工作流引擎就可以了嘛。工作流引擎不是萬能的,它只能解決一部分問題,更多的問題還需要我們的分析人員去分析與處理。

最後,企業信息化就是一次改革,這特別集中地體現在了業務流程分析這一部分。當我們詳細分析了客戶現有的業務流程以後,應當進一步思考這樣的流程是否合理,是否值得改進。信息化對於企業流程管理的衝擊是巨大的,最典型的實例就是ERP。ERP的前身是MRP(Material Requirement Planning 物料需求計劃)。起初,企業也就是希望有一套軟件系統來管理它們的倉庫。後來,企業領導希望他們在進貨的時候能有一定的採購計劃,避免出現倉庫中的物資擠壓,MRP就出現了。然後呢,企業開始思考整個生產製造的鏈條管理,MRPII的概念出現了。再然後呢,物料需求的動因是生產的需求,生產需求的動因是銷售的需求。企業要真正做到零庫存,就必須切切實實地把從銷售到採購的每一個環節都管理好,ERP的概念就出現了。一個典型的信息化流程改進的例子。

ERP對企業流程改進的思路是宏大的,但我們在分析每一個系統的時候不可能有如此宏大的雄心與抱負。一般來說,我們可以用以下思路來進行我們對流程改進的分析:清除低效環節、簡化業務瓶頸、整合可用資源,以及將繁瑣任務自動化。

清除低效環節,就是清除那些耗費成本高而收效又低的環節,最典型的就是過量的庫存。過量的庫存原因很多,有可能是供銷環節沒有處理好而造成的過量採購,或者生產過剩,也可能是生產計劃沒有制訂好而產生活動間的等待。除此之外,還有重複的活動,等等。

簡化業務瓶頸,就是分析業務流程中影響整體進程的瓶頸業務,並有效地簡化它。如很多業務審批流程中都有一個受理環節。大量業務都集中在一兩個人來集中受理,根本忙不過來,造成整個流程的效率下降。解決的辦法有兩個:一個是採用信息化的手段進行批量受理,加快處理效率;另一個是將受理環節的任務分散到更多崗位中,降低受理人員的工作量。

整合可用資源,就是更大範圍地整合各個部門、不同職能的人員與社會資源,更加協同地來完成任務,這也是計算機信息化管理最拿手的方面。製造業的供應鏈管理是最典型的例子,因爲實在太經典了我就不累贅了。醫院系統也是一個不錯的例子:完成了身體檢查,醫生就立即知道了檢查結果;醫生開完藥,收費處就知道收多少費,藥房就知道拿什麼藥。

最後是自動化繁重操作。在財務系統中開了銷售單,就直接開發票了,並且直接形成報稅數據;在網上報完稅就知道該繳多少錢,甚至不用去稅務局,直接上銀行繳,等等等等,不勝枚舉。繁重操作自動化,正是信息化系統價值的體現。


我們應當怎樣做需求分析:用例說明

當我們進行業務流程分析時,只空對空而不落到紙面上是不可以的。過去,在面向過程的時代,我們繪製DFD圖、流程圖,以及編寫流程說明來描繪這一部分分析;而現在,在面向對象的時代,我們則是繪製行動圖、狀態圖,以及編寫用例說明來完成這部分工作。

在這部分工作中,編寫用例說明應當是最主要的工作,之後在一些關鍵部分輔之以行動圖、狀態圖。現在我們來看看用例說明應當怎樣編寫。

毫不疑問,做用例分析首先是要繪製出用例圖(前面已經說過了)。圖形的最大優勢是能夠形象生動地描述我們的分析,但它最大的缺點是會遺失許多的細節信息,因此我們必須要對它進行進一步的文字描述。




由於不同的人對用例的理解不同,格式也不盡相同,但一些基本的元素是一樣的。以上表格是我採用的用例說明格式,其中用例名稱、用例描述、參與者、前置條件、事件流、後置條件是公認的、用例說明的基本元素。

用例標識:就是用例的編號,一般採用“項目編號-子系統編號-模塊編號-序號”來編號。

用例名稱:沒啥可說的,就是用例圖中該用例的名稱。注意用例的命名規則:用例名稱通常是一個動詞短語或短句,而不是一個名詞短語。它可以是一個動詞(如:自動考覈),一個動賓短語(如:提取存款),一個被動句(如:發票填報),或者一個主謂句(如:用戶提款,這個不推薦,因爲主語就是參與者,顯得有些多餘)。

用例類型:在我看來,不同類型的用例,其用例說明的格式是不一樣的。以上給出的是“業務操作”類用例的格式,它更加着重地在描述業務操作的流程。而“查詢報表”類用例則沒有什麼流程,它更加着重地在描述報表格式及顯示內容(後面再給出)。還有用例類型還包括“子用例”、“擴展用例”。

用例描述:對該用例的功能定義、要實現的業務需求,以及誰(參與者)應該如何使用進行描述。同時,這部分還可以整體概述實現業務需求的主要流程,以及與其它用例、其它外部系統的關係。通過用例描述,閱讀者可以對該用例有一個整體的認識。

參與者:用例圖中該用例的參與者,通常是業務操作的觸發者和施與對象(如外部系統)。

觸發事件:誰幹了什麼,觸發了這個用例。

前置條件:在觸發該用例相關操作前必須達到的條件。

事件流:這是用例說明中最重要的部分,它詳細描述了該用例可能出現的所有流程。
1. 基本流程:另一個名稱更能表達它的意義:最佳流程(The Best Flow)。它描述的是該用例以最佳的、最正常的方式流轉,沒有出現任何異常,並且最終成功完成操作的流程。基本流程在編寫時,應當通過數字對流程中的每一步進行編號。
2. 擴展流程:或者叫“分支流程”,它描述的是基本流程在流轉過程中可能出現的所有分支。擴展流程最大的特點就是,它應當是在基本流程的某一步驟發生的分支,因此它的編號規則是“基本流程號+序號”。基本流程號就是發生分支的那一個基本流程的編號。在同一個基本流程上發生多個分支時,它們的序號從1依次開始編號。
另一種情況是,某個擴展流程本身擁有多個步驟,這時應當在“基本流程號+自身序號”的基礎上再添加序號,如“2.1.1”。
擴展流程在描述時,應當首先描述進入這個分支的條件,即“如果××則××”、“當××時××”。
3. 異常流程:就是發生異常情況時的處理流程。注意,用例說明是站在用例角度進行的說明,因此這裏並不是我們通常一樣的發生程序異常的處理流程,而是用戶在處理業務操作時發生的異常情況,如:如果顧客不能提供身份證,則••••••

後置條件:又稱爲“成功保證”,就是執行基本流程獲得成功以後所達到的狀態(條件)。後置條件往往體現的是執行該用例的最終目的。如:完成用戶檔案的填寫並提交。

非功能需求:簡稱爲“URPS+”,即可用性(Usability)、可靠性(Reliability)、性能(Performance)、可支持性(Supportability)以及其它(+)。這一部分的需求分析相當重要而又最容易被忽略,後面我們再詳細討論。

假設與約束:就是隱藏於業務功能中的各項規則與條件,如各種邏輯條件、計算公式、環境限制等等。

優先級:沒啥可說的,最關鍵的是怎麼去評定。這裏我賣一個官子,在需求評審階段,我會給大家一個比較準確而又可操作的評定方法。

除此之外,我還往往在每一個用例說明的後面與該用例相關的需求列表,便於需求跟蹤。用例分析實質是需求人員的一份設計。既然是設計就可能出現偏差,最終偏離原始的需求(這種情況特別容易出現在日後的升級維護中)。因此,將需求列表附在用例後面,便於日後的需求評審與確認。當每次需要升級時,則添加上新的需求,或對以往的需求進行更新。


我們應當怎樣做需求分析:查詢報表分析

在我以往的用例分析中,使用這樣格式的用例模式,對於大多數業務操作流程來說是得心應手的,但對於有些功能來說總感覺不對勁。感覺不對勁的,就是那些查詢、彙總與報表功能。對於這部分功能,需要我們描述的不是什麼操作流程,而更重要的是那些數據項、數據來源、報表格式、數據鏈接,以及使用者、使用頻率的說明。而這些,在以往的用例說明格式中統統都沒有,怎麼辦呢?俗話說“東西是死的人是活的”,把我們的用例格式改改吧。




這是我設計的查詢報表類用例的格式,同時還可以在後面配上報表的格式。你也可以根據需要設計你自己的格式,用例不是什麼陽春白雪的高級玩意兒,而是溝通你、用戶、開發設計人員的橋樑。該說明的都說到了,該分析的都分析了,大家都能看明白,並以此爲根據去完成各自的工作,這纔是用例說明的實質,其它神馬都是浮雲。

報表作用:就是描述參與者使用這個報表做什麼。如果有多個參與者,每一個都應當描述。

報表內容:用簡短的話描述一下。

輸出列:羅列報表的輸出列,如果需要的話,還應對輸出列進行說明,或描述它的數據來源。

使用頻率:參與者使用它的頻率,便於設計者考慮報表的查詢效率。

數據鏈接:哪些數據項有鏈接,鏈接到什麼報表,或顯示什麼數據。

最後依然是那個需求列表,便於業務需求的跟蹤。

查詢報表的需求分析與一般的業務操作的需求分析存在着巨大的差異。而許多需求分析人員沒有認識到這一點,這往往導致對查詢報表的分析不到位,爲項目的研發帶來風險,因此在這裏我們認真探討一下。

一個有效的報表,往往不是對數字的簡單堆砌,它通過一組一組的數據,揭示的都是一些客觀規律、複雜活動與發展趨勢。客戶方的領導,特別是那些中層和高層領導,通過對這些報表的閱讀,就可以掌握他們的工作進程、加強他們的人員管理、發現他們的管理漏洞、指導他們的戰略決策。總之一句話,每個報表都有他們的設計意圖。

比如說,一份工作月報,領導希望看到的,是按時間、按項目、按部門統計的各項工作的進展情況,以及有哪些異常情況,以便領導監控各項工作能夠順利完成;一份銷售報表,領導希望看到的,是按產品、按區域、按顧客類型統計的各項產品的銷售情況,以便領導制訂銷售計劃與各種營銷戰略。沒有弄清楚一個報表的真實意圖,就不算真正理解了這個報表的業務需求。

同時,報表的數據項應當都是來源與系統中各項操作的結果數據。許多業務系統的操作流程都是紛繁複雜的,其中還包括各種情況。更復雜的,一些商業智能與分析決策系統,報表所需的各種數據,甚至來源與各種各樣的外部系統。分析一個報表的數據來源,就是在梳理各種業務流、數據流,以及各種數據間的關係。如果這方面的分析不到位,最終設計出來的報表往往是不準確的。

另外,用戶使用報表的頻率,常常決定了報表設計的方式。如果報表中的數據總是在實時變化,並且用戶總是在密切關注這些數據的變化,那麼報表必須設計成實時查詢的;如果用戶並不是十分關注數據的實時變化,並且總是以天(或者月,或者年)來查看報表,則報表可以設計成按天(或者月,或者年)來預運算統計數字,使得報表查詢效率顯著提高,可以保證更多的併發訪問。

最後,一個報表的核心就是展現給客戶的報表格式,以及報表與報表間的各種鏈接。需求人員在進行需求分析階段,應當準確地與客戶敲定這些格式,並最終在用例說明中體現出來。報表格式是否體現客戶的意圖,報表數據項是否都能在系統中取到,數據間的邏輯關係是否正確,報表格式是否技術可行,都是需求分析人員在前期就必須要分析到位的內容。否則,報表是項目後期可能出現頻繁需求變更的重災區。

所有這些分析,都體現在了我提供給大家的用例說明格式中。報表作用體現的是報表對於不同用戶的真實意圖;輸出列體現的是對各個數據項及其數據來源的說明;假設與約束羅列的是報表中各個數據項的運算公式、數據規則與約束;還有使用頻率、數據鏈接、非功能需求,以及最後的界面原型,等等。只要我們把這些都分析到了,我們的查詢報表就分析到位了。


我們應當怎樣做需求分析:子用例與擴展用例

用例模型作爲UML中4+1視圖中非常重要的一員,非常集中地體現了面向對象的分析與設計思想。用例模型將現實世界中連續的一個一個業務流程,按照場景劃分到了一個一個的用例中。由於場景的出現,使得用例中的業務流程存在着高度的內聚性,從而成爲了日後各種對象的雛形。同時,在用例分析中,又將那些存在於各個用例中的,相同或相近的業務操作提取出來,形成一個一個的子用例或擴展用例,又體現了面向對象設計中的複用性。現在我們來談談用例分析中的子用例與擴展用例吧。

前面我們在用例說明中提到了基本流程。基本流程就是所有步驟都非常理想地正確執行,並最終完成所有操作的那個“最佳流程”。在基本流程中,可能有些步驟是多個用例都共有的,可以相互共享的流程。將這部分流程提取出來形成的就是子用例。子用例應當是在邏輯上相對獨立的一系統流程組成的用例。這個用例應當是抽象的,沒有自己的參與者,只有在調用它的用例中,才能真正明確它的使用者。




如圖是一個子用例使用的例子。圖中,用例“調整前信息查詢”、“調整後信息查詢”、“調整前時間段查詢”、“調整後時間段查詢”都用到了“按單位彙總考覈結果”。它們是一種使用關係或者包含關係,因此被繪製成一條虛線,從使用者指向被使用者,並標註爲use或include。

另外,在用例中還存在許多擴展流和異常流。當系統在運行到基本流程中某個步驟時,由於滿足了某個分支條件或異常條件,這時系統就從基本流程流轉到了擴展流或異常流中。擴展流和異常流其實不那麼涇渭分明。在業務邏輯上擴展流依然是一種正常的操作,僅僅只是正常操作的另一個操作,而異常流其本身就是有什麼東西不對勁了,需要進行一些異常處理,比如用戶密碼輸錯了、用戶忘帶身份證了,等等。擴展流和異常流最終都可能回到基本流程中,也可能不能回來,而從另一個結束點結束。

與子用例相似,擴展流和異常流中的流程如果相對獨立、可以爲其它流程所共享,則可以提取出來,形成一個單獨的用例,叫擴展用例。如果擴展用例是直接從基本流程中某個環節擴展出來,則該環節被成爲擴展點,進入擴展用例的條件叫擴展條件。在用例圖中,擴展關係被繪製成一根虛線,從擴展用例指向被擴展的用例,並標註爲extend。

用例分析中對子用例與擴展用例的分析,使我們對系統的設計,從一開始就將公共的、可共享的部分提取出來,使我們在日後的設計與開發中得以很好地複用,提高了系統的內聚並降低了系統的耦合,是一個優秀軟件設計的開始。


我們應當怎樣做需求分析:行動圖和狀態圖

前面,我們耗費了大量的篇幅來討論用例分析及用例圖。用例圖,無疑是功能分析、角色分析,以及流程分析的利器,它將我們要開發的系統,清晰而詳盡地描述出來。但是,正如任何事物都有兩面性,用例圖也不例外,也有自己不利的一面。在我看來,這集中體現在兩個方面:只見樹木不見森林、不生動形象。

什麼叫“只見樹木不見森林”呢?就是說,用例說明中對業務流程的描述,過早地將系統的整體流程,分散到了各個用例中了,丟失了對業務流程的整體描述。不生動形象,則是說用例說明中對流程的描述都是用枯燥無味的文字來表述的,缺乏生動形象的圖形表示。針對這些不足,UML的另外兩種視圖,可以有效地彌補用例圖的缺陷。它們就是行動圖與狀態圖。

行動圖(Active Diagram),比較類似於我們過去繪製的流程圖,是UML中描述流程與分支的視圖。在行動圖中,往往是從一個實心圓的起始節點開始的。最頻繁使用的則是活動節點了,它表示的是業務流程中的一項活動。活動節點可以表述爲一個活動短語(如下訂單),可以表述爲一個表達式(如len=a.length+x),還可以表述爲一個消息(如send(msg))。同時,將各個活動節點連接起來的一個個實線箭頭,表明了各種活動之間的流轉順序。



在各種業務流程中,毫無疑問會有許多的分支。在行動圖中,分支用一個菱形來表示。一個指向菱形的箭頭,表示流程進入分支,另外兩個或多個從菱形伸出的箭頭,則表示不同條件下的分支流。而菱形本身,則表示爲一個條件判斷語句。

另外,業務中的各個流程還會分岔與匯合的情況。分岔,表示在某個時間點上,同時開始兩個業務流程,這兩個業務流程是同步進行的。分岔用一個入箭頭,一根橫槓,與兩個出箭頭表示。匯合,則表示,只有在兩個流程都完成的情況下,纔會進入下一流程,否則只能等待。
匯合則用兩個入箭頭,一根橫槓,與一個出箭頭表示。

最後,用一個或多個帶環的實心圓,表示的是活動圖的終止節點,代表了業務流程的終結。以上這些元素,就組成了一個基本的活動圖。然而,基本的活動圖還不能完整的反映我們的業務流程,因此我們還需要在基本活動圖的基礎上增加元素。現在我們來看看泳道與業務對象流。



如圖就是一個帶泳道的活動圖,圖中每個泳道代表一個參與者的業務操作,而整個圖形表述了多個參與者間的協作過程。起初我比較愛繪製這樣的活動圖,但後來常常感到繪製泳道是一件比較繁瑣的事情。既然如此,我們就改改吧。



這張圖纔是我最愛使用的行動圖。圖中,將參與者由繁瑣的泳道改爲了用例圖中的小人。同時,在這張圖中還增加了對象流與對象。圖中,自動考覈結果、申辯申請單、調整後考覈結果,都是數據對象,是該流程中相關環節操作的結果。從活動節點指向對象的虛線箭頭,則表示了一個對象流,如“申辯申請”活動指向“申辯申請單”的虛線箭頭,表示了申辯申請活動的最終結果是產生申辯申請單;從“調整後考覈結果”指向“過錯追究”的虛線箭頭,表示過錯追究活動讀取了調整後考覈結果。

當然,活動圖還有其它的元素,但我個人認爲其實並不實用,使用以上元素就足以表述我們的業務流程了。活動圖打破了子系統與子系統的壁壘、用例與用例的壁壘,使我們能夠從整體上了解整個系統的流程,因此常常使用在對整個系統的概述、對整個子系統的概述,以及對整個功能模塊的概述中。同時,與其它視圖一樣,活動圖也應當有它的文字說明,以便對圖中的每個活動節點、分支進行描述。但對於一些流程相對簡單,甚至沒有什麼流程的查詢報表類功能模塊,繪製它們的活動圖則顯得有些牽強附會,因此我們要靈活掌握。

除了活動圖,我們似乎對需求的描述還缺少點兒什麼,那就是對關鍵對象中流程中狀態變化的描述,在這種情況下,我們的狀態圖就上場了。

在使用狀態圖時,一個非常關鍵的概念就是,一定是對某個關鍵對象的狀態變化的描述,而這些狀態變化一定是在某個業務流程的大背景下進行的。下圖是一個疑點數據整個生命週期的狀態變化圖。圖中,與行動圖一樣,一個實心圓點代表的是流程的開始,圓邊的方框代表的是對象生命週期中的各個狀態,狀態節點間的實線箭頭代表的是狀態的切換,箭頭的文字描述是觸發狀態切換的事件。與行動圖一樣,狀態圖可以有分支、分岔、匯合,並最後以一個或多個帶環的實心圓結束,代表對象生命週期的終結。



在需求分析中,狀態圖並不是必須的,它僅僅出現在你認爲需要對某個對象的狀態進行說明的時候。


我們應當怎樣做需求分析:業務領域分析

在需求分析工作中,最後一項分析工作就是業務領域分析啦。業務領域分析,就是對需求分析中涉及到的業務實體,以及它們相互之間關聯關係的分析。前面我們談到了功能角色分析,或者說用例分析,它是從整體的角度對整個系統人機交互的分析與整理。隨後我們談到了業務流程分析,它是在對系統人機交互的分析與整理的基礎上,更加細緻的去分析和整理那些業務流程,以及組成這些流程的一個個業務操作。業務流程分析是對系統進行的一種動態的分析,分析的是那些行爲,那些操作。但是,所有的行爲,所有的操作,最終施與的對象都是那些實體。這句話怎麼理解呢?比如,我們執行填寫操作,施與的對象必然是那些表單,最終產生的結果必然是形成一份完整的表單,表單就是那個行爲施與的對象。再比如,我們執行查詢操作,施與的對象必然是一個報表,最終產生的結果必然是查看到了這個報表的結果。這裏的表單、報表,都是存在於系統的靜態實體,它們中的大多數也最終以數據結構的形式持久化保存於系統的數據庫中。因此,系統中應當有哪些實體,這些實體都有哪些屬性,被賦予了哪些行爲,它們之間的相互關係是怎樣的,就成爲了業務領域分析的重要內容,而業務領域分析也就成爲了對系統進行的一種靜態分析。

我們的軟件系統,毫不誇張地說,就是對現實世界的真實模擬。現實世界中的事物,在軟件世界中就被模擬成一個對象。該事物在現實世界中賦予什麼職責,在軟件世界中就賦予什麼職責;在現實世界中擁有什麼特性,在軟件世界中就擁有什麼屬性;在現實世界中擁有什麼行爲,在軟件世界中就擁有什麼函數;在現實世界中與哪些事物存在怎樣的關係,在軟件世界中就應當與它們發生怎樣的關聯。這正是面向對象編程的核心思想。



我們進行業務領域分析,就是基於這樣一個思想進行的。什麼叫業務領域,就是客戶所在的知識領域,譬如財務人員所在的是財務領域,稅務人員所在的是稅務領域,營銷人員所在的是銷售領域。不同的知識領域擁有各自不同的領域知識,需求分析人員就應該通過客戶中的領域專家去學習這些知識、掌握這些要點,並最終體現在我們的需求分析中。然而,這必然是一個長期的過程。從這個角度說,業務領域分析不僅出現在需求分析階段,還應當貫穿與設計階段、開發階段、測試階段,甚至延續到後期的維護與升級。從另一個角度講,現在的軟件研發概念,已經不再是一錘子的買賣,而是延續到數年的不斷升級完善中了。而軟件的升級完善,從本質上說就是對業務領域不斷深入的認識。我們對業務領域的認識深入一點兒,我們的軟件系統就完善一分,再深入一點兒,就再完善一分。這就是世界級軟件分析大師Eric Evans提出的領域驅動設計的核心思想。

因此,我們進行業務領域分析,就是通過與用戶進行交流,掌握領域知識,然後繪製成業務領域模型,去指導我們軟件開發的過程。日後我們去設計開發系統時,應當設計哪些類,類中都應當有什麼屬性和行爲,以及怎樣去設計數據庫,都是以這個領域模型爲基礎的,雖然有時並不完全與領域模型完全一致。過去,沒有一個切實可行的方法來指導我們的業務領域分析,而現在,我們可以通過兩種分析方法一步步進行:原文分析法與領域驅動設計。隨後,我們將就這兩種方式進行詳細分析。


我們應當怎樣做需求分析:原文分析法

原文分析法(Textual Analysis),是在用例說明與流程分析的基礎上進行的業務領域分析,是一項在需求研討會後整理和分析需求的工作。當我們完成了用例圖的繪製,爲每個用例編寫出用例說明以後,原文分析的工作就可以開始了。要講解原文分析,我們還是用一個實例更簡單明瞭:



這是一個實際項目的用例說明。在進行原文分析的時候,我們首先要做的事情就是對用例說明中事件流部分的文字描述,提取其中的名詞。在這個實例中都有些什麼名詞呢?這些名詞我在用例中用藍色標註了出來,經過整理就是這些:觸發器、考覈指標(簡稱指標)、執法行爲、指標定義、過錯標準(過錯判斷標準)、過錯行爲、考覈結果、年度、月份、機關、分子數、分母數、過錯數、正確率。

領域模型中的實體,往往就在我們通過原文分析提取出來的這些名詞中,但需要我們進行進一步分析。並不是所有名詞都可以成爲實體,那麼哪些可以呢,而哪些又不能呢?首先,系統外的參與者不能。系統外的參與者是觸發本系統某個事件的人或者物,但它本身存在於系統之外,比如用戶使用鼠標點擊了一個按鈕,而領域模型是描述系統之內的事物,因此係統外的參與者應當被排除。本例中的觸發器就是系統外的參與者(參見《功能角色分析與用例圖》),它應當被排除。

其次,系統之內的事物轉化到領域模型中,可能會變成兩種東西:實體與實體中的屬性。什麼變成實體而什麼變成實體中的屬性呢?自身有自己的屬性,可以成爲系統中行爲的執行者或施與者的,纔是實體。比如考覈指標就是實體,因爲它有它的考覈標準、過錯行爲、分子數、分母數、過錯數、正確率等屬性,它在系統中會去執行考覈,所以是實體;分子數是不是實體呢?它僅僅是一個數據,沒有自己的屬性和方法。另一個判斷是實體還是屬性的方法就是判斷它將如何持久化。如果一個事物被持久化到數據庫中時是一個表,則是一個實體;如果僅僅是表中的一個字段,則是一個屬性。

然而,是實體還是屬性並不是那麼絕對,關鍵看系統對這個事物進行怎樣的處理。比如過錯標準是一個實體還是一個屬性呢?如果我們在系統中僅僅是一個文字描述則是考覈指標中的一個屬性,如果需要對它進行分解,有它的判斷公式,需要讓它去執行判斷,則應當是一個實體。在需求分析的初期,可以先將其設計成一個屬性,待日後的細化階段再進行調整。

另外一個非常重要、值得我們着重關注的地方是名詞的多義性。在本例中,我們考察一下“過錯行爲”這個名詞。“一種過錯行爲”與“一個過錯行爲”顯然不是一個概念。“一種過錯行爲”代表的是一種類型,有它的過錯定義與判斷標準;“一個過錯行爲”則代表的是一個實例,一個執法行爲中的某個錯誤的行爲。正因爲它們概念上的差異,我們在領域模型中將其分爲“過錯類型”與“過錯行爲”。

經過一番分析,我們繪製出了一個基本的領域模型。毫無疑問,這個領域模型使用的是一個類圖,實體在圖中就是一個個的類。同時,我們將各個類之間的關係標註出來:一對一、一對多、多對多、聚集、組合、繼承,等等。爲了提高模型的可讀性,我們在必要時可以標註關係的名稱。如考覈指標與執法行爲之間是類型與實例的關係,等等。

現在,讓我們重新回到原文分析。這次要分析的不是用例說明中的名詞,而是動詞,在本例中我用紅色標註出來。最後,我們整理出這些動詞:觸發、執行考覈、預警、採集、判斷、是過錯、是正確、打分、統計。

對用例說明中的動詞分析,是爲了定義各個實體之間的各種行爲。同樣,並不是所有動詞都是實體的行爲。參與者的行爲顯然不是實體的行爲,應該被排除掉,如:實例中的“觸發”。還有一些動詞是某個行爲的一個細節,如:“是過錯”、“是正確”,被合併到“過錯判斷”中。最後,將行爲添加到行爲的執行者中。最後繪製出這樣一個領域模型:



領域模型有別於後期的分析模型,其中最關鍵的就是目的,它的目的僅僅是分析需求,因此在很多地方會比較模糊而不考慮技術實現,比如本例中的“指標定義”、“過錯標準”。另外一個比較關鍵的地方就是,系統中的行爲到底由誰來執行,這個標準常常是說起來容易做起來難。我給大家的建議是參考GRASP中的“信息專家”模式。

GRASP是一種職責驅動設計的系統分析方法,它的“信息專家”模式是這樣描述的:應當將系統中的行爲交給信息專家去執行,而信息專家就是掌握着執行該行爲所需數據的實體。在本例中,由於考覈指標掌握着指標的定義,還有那些執法行爲,所以它可以執行考覈,而過錯類型則掌握着過錯標準,因此可以執行過錯的判斷。注意,這裏的“執行”什麼行爲,是軟件意義上的概念,即一個類可以擁有什麼行爲,而非現實世界的概念。要知道現實世界中的事物是不可能有主動執行什麼操作的能力的。

過去我們拿到需求不知道該怎樣去業務領域分析。有了原文分析方法,給了我們一個簡單可行、易於操作的方法,讓我們準確而高效地完成業務領域分析。


我們應當怎樣做需求分析:領域驅動設計

2007年,世界級的軟件分析大師Eric Evans發表了他的經典著作《領域驅動設計》,進而形成了一套獨特的軟件分析與設計方法,簡稱爲DDD(Domain-Driven Design)。在領域驅動設計思想中,有許多是涉及到需求分析領域的先進方法,我把它歸納爲有效建模、統一語言和持續學習。

有人說:大師所站的高度實在太高了,是生活在太空裏的,所以我們要追隨大師就只有因爲缺氧而死掉。我認爲這句話說得非常生動,學習大師真的不是一件容易的事,把大師的思想落實到我們的工作中更難,常常還伴隨着一些不小的風險,學習伊大師也是一樣的。

伊大師一上來就提出了要有效建模的思想,我當時立馬就暈菜了。按照這個思想,我們應當在業務研討會上,與客戶討論業務需求的時候就開始現場建模了。這!怎麼可能呢?客戶看得懂那些專業的、抽象的模型嗎?我們能拿着模型與客戶交流嗎?這是不是在浪費時間?

的確,伊大師提出了有效建模思想,與其它很多諸如在會後分析整理時進行的原文分析方法大相徑庭。同時,這個思想認爲,我們應當與客戶代表形成一種統一的語言,一種混合語言。這種語言,既有軟件技術中的元素,又有業務領域中的術語,同時,它又是技術人員與業務人員都能理解的語言。使用這個語言,技術人員與業務人員就是在用同一語言在溝通與討論問題,這種溝通的障礙就得以消除。

道理簡單實踐難,什麼是有效的建模,什麼是統一的語言呢?經過無數的實踐與嘗試,我逐漸開始明白了。首先,什麼是有效的建模呢?當我們作爲非專業人員去看一個建築設計師繪製的圖紙時,我們一看就明白這是一棟樓房,那是一座橋樑,爲什麼?因爲圖紙形象生動,沒有那麼多專業術語,我們一看就明白了。軟件中的設計圖也是一樣的道理。

當我們站在技術人員的視角去繪製設計圖時,客戶必然看不懂,因爲圖中使用的都是專業的術語、專業的符號,表達的都是專業的設計思想。反過來,如果我們站在業務人員的視角去繪製設計圖時,情況就不一樣了。如果一個用例圖,圖中的功能都是客戶日常經常做的業務操作,並且命名都是業務人員能夠理解的業務術語,試問客戶會不理解嗎?同樣,在領域模型中,我們按照客戶的思路,運用客戶的術語,去繪製一個一個的對象,按照他們的思路去描繪對象間的關係,描繪對象間的操作,他們真的就會看不明白嗎?這說得似乎有一些抽象,我們舉一個實際的例子吧。

有一次,我與客戶在討論一個考覈系統,首先客戶描述着他們的需求:
客戶:我們這個考覈系統是由許多個考覈指標組成的,每個考覈指標就標誌着我們的某項工作的完成情況。每個考覈指標中有一個分母數,標誌某段時間所有應當完成的工作數量,有一個分子數,標誌這段時間正確完成的工作數量,最後還有一個過錯數,標誌那些錯誤的,或者沒有按時完成的工作數量。
需求人員:爲什麼是分子分母?
客戶:因爲最後要計算正確率,用正確率來考覈一個單位完成工作的情況。
這樣,我們在紙上繪製出一個考覈指標,在屬性中寫下分母數、分子數、過錯數、正確率。

需求人員:那麼每個考覈指標都有一個過錯判斷標準了?
客戶:當然啦,每個考覈指標都有它的過錯判斷標準。一個考覈指標可能會有多個過錯行爲,每一個過錯行爲都有各自的過錯判斷標準,任何一個過錯了,這個執法行爲就算過錯啦。
需求人員:先等等,你剛纔提到執法行爲了。執法行爲和考覈指標是什麼關係?
客戶:哦,執法行爲嘛,就是執法人員對某個用戶執行的一次業務操作。考覈指標中的分母數就是所有執法行爲的個數;分子數就是正確的執法個數;過錯數就是錯誤的執法個數。
這樣,我們就繪製出這樣一個草圖:



客戶看了這個草圖有些不同明白:過錯類型是什麼東西?
需求人員:過錯類型就是某種類型的過錯行爲呀,它定義了某種過錯行爲,有它的過錯判斷標準。下面這個過錯行爲就是那些具體的過錯,比如張三今天犯了什麼錯,李四明天犯了什麼錯。
客戶:哦,明白。這兩個箭頭怎麼跟其它箭頭不一樣,後面還跟了個菱形框?
需求人員:哦,這代表的是包含關係,表示一個考覈指標包含了多個類型的過錯行爲呀。

經過一番交流,我們已經明白客戶的意思了,客戶也明白我們畫的圖了。大家對彼此的交流都比較滿意。

所有的愛情都是以浪漫開始的,需求分析也不如此。隨着需求分析的不斷深入,我們發現問題了。在這張圖中,我們把執法行爲與過錯行爲僅僅描述爲一對多的包含關係,似乎沒有什麼特別的。但對大量考覈指標具體需求的分析,我們才發現其實不是這樣簡單。當考覈指標只有一種過錯行爲的時候,那非常簡單,這個過錯行爲對就是對,錯就是錯。但當考覈指標存在多種過錯行爲的時候,情況就複雜了,必須分成三種情況:

1. 一個執法行爲同時包含多種過錯行爲,每個過錯行爲就是一個考覈點,任意一個考覈點錯了整個就判錯,只有所有考覈點都正確才判正確。這種情況就像填一個表單,所有數據項都填對了纔算對,任意一個錯了就算錯,然後畫出這樣一個對象圖:



2. 雖然一個考覈指標定義了多個過錯行爲,但它把所有執法行爲分爲多個類型,每個類型的執法行爲只對應一個過錯行爲,這個過錯行爲對就是對,錯就是錯:



3. 最後一種就是那些限期完成的考覈指標,正確的行爲只有一個:按時完成的行爲,過錯行爲卻有兩個:逾期完成與逾期未完成。



雖然圖形有些複雜,但這正是代表了現實世界業務的複雜性。我們拿着這些圖與客戶進行了簡單的描述,由於圖中的所有元素都是用客戶熟悉的術語描述的,因此他們很快就能夠理解。同時,開發人員拿到這樣一個圖,很快就制訂了四套不同的方案,來分別解決四種不同的情況。

隨後,在對這四種情況更加深入的分析時,我們發現第一種情況在計算過錯數時似乎有一些問題。在第一種情況中,一個執法行爲包含了多個過錯行爲,如果出現了過錯,過錯數算幾?假如一個執法行爲包含三個過錯行爲,如果都做對了,分子數算1;但假如有2個過錯行爲錯了,過錯數算2?還有那一個正確的行爲呢?這似乎有些矛盾!當我們向業務人員提出這個問題時,他也有些懵了,這樣的結果似乎是我們雙方都沒有預料到的。經過反覆的思考與討論,最後我們做出這樣的決定:將原有的過錯數拆分成過錯戶與過錯數。在以上情況中,如果一個執法行爲有2個過錯行爲錯了,過錯戶爲1,過錯數爲2。試想,如果不對需求進行如此深入分析與理解,能發現這樣的問題嗎?如果不及早發現這樣的問題,是否會給項目後期帶來巨大的風險?

應該說,從最初的粗淺認識,深入到後來對四種情況的認識,正是體現了DDD的另一個思想:持續學習。需求人員在開始一個新的管理系統的分析工作時,都有可能面臨着一個全新的業務領域。在這個領域中,他們不可能一夜成爲專家,也不必要成爲專家。他們需要時間去學習領域知識,但這並不意味着學習所有的領域知識,而是與軟件相關的領域知識。做財務軟件,你不必考財務師,但你必須要學會與財務軟件相關的財務知識。你對領域模型的認識被延伸到了整個軟件生命週期中,包括之後一次一次的升級完善。你每認識深入一點兒,就可能會體現到你的分析設計中,並最終體現在開發的軟件中。你對領域知識認識再深入一點兒,軟件就再完善一分。


我們應當怎樣做需求分析:非功能需求

我曾經看過許多關於需求分析的書籍,老外寫的,國人寫的,都有。但我總體就是一個感覺:累。各種各樣的分析、各種各樣的視圖,讓人眼花繚亂。爲什麼會這樣呢?不得不說,需求分析是一個太寬泛的概念了,不同的行業(商業的、管理的、遊戲的),不同類型的軟件(底層的、桌面的、網絡應用的),不同的設計方式(面向過程的、面向對象的),需求分析的過程都存在着巨大的差異。要制訂放之四海而皆準的方法談何容易。即使同一類型的軟件,它們也存在着各自的特點,有的問題大多數軟件都不用考慮,而它必須考慮。正因爲如此,許多關於需求分析的方法和書籍描述得挺複雜的。

但我要說,我們做需求分析應當化繁爲簡,不必去拘泥於那些過程。怎樣化繁爲簡?尋找適合自己的,避免做過度分析和設計,這種思想也是敏捷開發的精髓。比如我所從事的管理軟件的研發,關注業務流程、關注業務實體、關注規則約束,功能方面的需求就分析完成了大半。然後再關注查詢報表、關注外部接口、關注打印導出等細小功能,功能方面就差不多了。

但是,我不得不說,需求分析人員最容易忽略的部分就是非功能需求。非功能需求更加靠近的是技術,是設計,是實現,是架構師關注的內容,是需求人員最不擅長的方面,這也是非功能需求爲什麼常常被忽略的重要原因。正因爲如此,架構師應當儘早參與到項目中,參與到需求分析中,儘早分析需求的技術可行性,儘早考慮性能、安全性、可靠性等非功能需求,儘早開始架構設計。

在非功能需求分析中另一個非常常見的錯誤,就是將非功能需求僅僅歸結爲一些放之四海而皆準的原則,比如專門拿出一章來描述報表查詢效率要怎樣、系統易用性要怎樣。誠然,這些原則性的東西是十分必要的,但許多非功能需求不能僅僅停留在這些基本原則上,要落實到對一個一個功能的分析中。

說這麼多虛的,咱們還是上實例吧。還是這個考覈系統,每天在上班後1小時內,將有90%的用戶會上線查看自己的考覈結果。因此,在進行考覈結果查詢功能的分析中,我們寫下了這樣的話:查詢必須高效(預計查詢數據量:xxx),並且支持高併發操作(預計併發用戶峯值:xxx)。有了這些描述,設計和開發人員會着重注意該功能的性能問題,測試人員也可以着重進行該部分的性能測試。

在另一個項目中,用戶需要對大量的數據進行選擇,進而完成製作清冊、下派、回退等操作。在前期的需求分析中,需求人員沒有仔細分析這些操作的易用性,沒有提供給用戶批量選擇等功能,直到試運行時才發現。當時系統到各基層試運行時,激起了巨大的民怨,給項目帶來了巨大的負面影響。多虧我們及時發現問題,加班加點完成了相關操作的批處理功能,才使項目得以順利推行。如此看來,非功能需求對於一個軟件項目是多麼重要。因此,我建議,在需求分析的細化階段,需求分析人員應當與架構師一起,一項一項地去分析每個功能的非功能需求,並在用例說明中記錄下有特殊非功能需求的功能,使我們對非功能需求的分析落到實處。

那麼哪些是非功能需求呢?我們可以簡單歸納爲“URPS+”,即可用性(Usability)、可靠性(Reliability)、性能(Performance)、可支持性(Supportability)以及其它(+)。而這5部分我們可以進一步細化。

可用性是一個非常寬泛的概念,它泛指那些能讓用戶順利使用系統的指標,包括易用性(易操作、易理解)、準確性、安全性(權限體系、訪問限制)、兼容性(服務器、客戶端的兼容度),等等。

可靠性就是系統可以可靠運行,包括系統成熟度(數據吞吐量、併發用戶量、連續不停機性能等)、數據容錯度、系統易恢復性,等等。

性能,我認爲是需求分析階段最主要的分析內容。用戶對性能的要求沒有止境,但現實卻是殘酷的。性能受到許多因素的影響,包括業務需求、軟件設計、數據庫設計、系統部署方式,等等。其中,業務需求和部署方式,對性能的影響是最大的,我們必須在需求分析階段就想清楚,解決掉。有一次,客戶提出了一個數據導出的功能,這看似一個非常普通的功能。但是經過仔細地分析我們發現,客戶在執行數據導出前的查詢時,如果選擇時間跨度數年,查出的數據量可能達到數十萬。要將數十萬數據一次性地導入到一個excel文件中,這不論從運行效率、系統穩定性,還是技術可行性分析都是不可取的。最後,我們經過與客戶的協商,一次性導出數據最大不超過2萬,同時提供了分頁導出的功能,可以讓他們選擇導出從第幾頁到第幾頁的數據。這樣,如果數據量大,客戶可以經過多次將數據導出,數據導出的性能得以保證。

系統部署架構對性能的影響也是巨大的。一個管理系統,是市級集中,還是省級集中,甚至全國集中,對性能的考量是不一樣的。市級集中不會過於擔心性能的問題;省級集中就必須要考量併發訪問量,是否要建立集羣;全國集中就必須考量是否使用消息隊列,所有流程是否有性能瓶頸,以及採用什麼技術架構更適於併發訪問等等。而這一切都是系統架構師應當考量的內容。

最後一個內容,也是最容易被忽略的一個內容,就是可支持性。可支持性,就是軟件的可維護性、易變更性。可支持性對於客戶是透明的,不可見的,因此客戶通常不關心這個。由於時間緊、人員素質參差不齊,這部分也常常爲管理者所忽略。但試問,誰沒有維護糟糕系統的痛苦經歷?誰們的系統維護了數年經過數次升級後還能維護?在需求分析與設計階段,可支持性實際上體現在,我們是否能有效識別系統可變的需求,並能夠提供合理的方案。這體現的也是架構師的功底。一次分析和設計ERP軟件的時候,我發現應付單需要生成憑證,隨後又發現應收單、採購單、銷售發票都要生成憑證。既然這麼多單據需要生成憑證,是否還有其它我們還不知道的單據也要生成憑證,是否可以有一個統一的接口。果不其然,覈銷單、工資單、固定資產覈定都需要生成憑證。最後我們設計成了一個統一的生成憑證接口。還有一次,我們發現客戶報表在查詢SQL、過濾條件、顯示列等部分經常變,因此設計成一套可配置的報表系統,大大提高了系統可維護性。

需求分析是一個撒大網的過程,而不是姜太公釣魚的過程。功能需求固然重要,非功能需求同樣重要。我們在進行非功能需求的分析時,除了制訂整體的原則以外,還要落實到各個具體的功能中,將這些功能所潛在的、特殊的非功能需求挖掘出來,提前進行分析設計,對於可行性不高的應及時與客戶商討,纔能有效地避免日後存在的這些方面的風險。


我們應當怎樣做需求確認:需求列表

需求分析是一個我們與客戶不斷溝通的過程,這個過程就如同我們與老闆的一次對話。老闆把你叫去,給你交待了一大堆任務。我們首先是仔細聆聽任務的內容,然後整理個一二三四。然後我們複述一遍老闆的意思:“老闆,我複述一遍,您看看我理解得對不對。首先,您要求我×××,然後×××,最後×××。”老闆:“恩,就是這意思,你照着辦吧。”之後,我們開始了我們的工作。這個複述的步驟相當重要,因爲人與人的溝通最大的問題就是失真。由於人在知識水平、觀點看法、性格特質的不同,聽者常常會誤解對方的意思。有了複述的步驟,誤解就會立即被糾正,溝通得以順暢。在需求分析中,這個複述的步驟就是需求確認。

但與一次簡單的溝通不同,需求分析是一系列複雜的溝通過程,它涉及到許多人,談論的是許多的事物。因此,一次簡單的口頭複述不足以滿足需求分析的需要。因此,需求確認是一系列的確認過程,每次確認都可能需要與不同的人,在不同層次的確認。最終應當形成到紙面,形成文檔性的東西,雙方簽字確認。這個過程中可以採用的一個好的方法就是原型法,最終產物應當是需求列表與需求規格說明書,最後結束於一場需求評審會,或者簽字確認會。

當我對無數失敗項目的分析總結之後,得出的一個重要的結論就是我們的項目需要對需求的跟蹤。大家想想,當一個項目持續數月,經過數輪的需求分析與設計,再經過數輪的需求確認與變更。用戶、需求分析員、系統架構師、設計人員、開發人員,甚至測試,一個一個的角色像走馬燈一樣加入進來。需求開始變得模糊不清,軟件設計的初衷開始偏離。開發人員不知道依據哪個標準開發,測試人員不知道依據哪個標準測試,甚至一些需求被人所遺忘。最終,等到軟件交付的時候,客戶說這不是他們所需要的,項目走向了失敗。問題出在哪裏呢?問題就出在,不論我們如何分析與設計,我們都要如實記錄原始的需求,並以此來驗證我們最終的軟件。這個如實記錄原始需求的文檔,就是需求列表。

需求列表,又稱之爲需求跟蹤表,是最原始的、用戶對業務需求的描述。它不摻雜任何需求分析人員對業務需求的分析與設計,而是以簡短扼要的語句,以業務人員的口吻表述的,今後要開發的這個系統應當提供給他們的各項功能。

首先,需求列表不摻雜我們對業務需求的任何分析與設計,這是需求列表的核心,也是它存在的意義。從用例模型到領域模型我們不難發現,它是一個分析與設計的過程。需求分析員對業務需求進行捕獲、認識、理解以後,需要結合軟件專業知識進行分析設計,還要聽取系統架構師和設計師對需求可行性的分析,最後才整理和編寫出用例模型。在這樣一個過程中,隨着業務需求複雜度的提高,以及各種技術分析的摻雜,最終的結果很有可能偏離原有的業務需求。這種偏離常常表現爲對業務需求正確性與完整性的偏離,即需求已經變味兒了,或者某些需求項目缺失。需求列表就是那個最開初的、最完整的、正確的業務需求。用這樣一個列表來開始我們的分析,最後用它來驗證我們的設計,使之成爲我們的分析設計之旅樹立的一個正確的航標。有了這樣一個航標,就可以使我們最終能夠到達一個正確的彼岸。

其次,需求列表應當是站在業務人員的視角,對業務需求的簡明扼要的描述。一個紛繁複雜的、業務龐大的管理系統,經過整理以後,被分解成一個一個的需求項目。每個需求項目是一句簡明扼要的話。簡明扼要意味着清晰易懂;分解成需求項目意味着分解複雜問題爲簡單問題。每一次與業務人員討論完業務需求以後,我們就整理成這樣一個需求列表,使我們與客戶的討論都有一個清晰明瞭的討論結果。當下一次與業務人員討論時,我們拿出我們上一次討論的需求列表,又使下一次的討論有一個基點,使業務討論能以演進的方式推進下去,提高我們的工作效率。

然而,需求列表中應當剔除那些客戶對系統設計的內容。前面我們提到,客戶,特別是那些對信息化建設有一定經驗的客戶,容易提一些對系統設計的期望,比如什麼功能應當做成什麼樣子,功能界面是怎樣的。客戶提的這些意見,也許不是最佳的,我們經過深入的分析設計以後,可能會提出一些更加合理的方案。因此,這樣內容不能成爲我們驗證系統功能的基石,因而不應當寫入需求列表中。需求列表描述的更應當是客戶對軟件功能的意圖,即客戶使用這個功能所達到的目的,而不是功能的具體實現。這一點我們在後面通過具體實例詳細說明。

最後,需求列表也不是一步到位的,而是經過由粗到細逐漸整理形成的。一個大的需求項目可以分解爲多個細的需求項目,進而形成一個樹狀的需求列表。需求列表應當細分到什麼程度呢?將系統需求描述清楚爲宜。簡單需求不需過多的細分,而複雜需求則需要儘量寫細一些。同時,需求列表也是一個不斷變化的過程,日後的每一次升級維護都需要不斷增添和修改需求列表,使其與實際系統保持一致。


我們應當怎樣做需求確認:一個需求列表的實例

現在我舉一個具體實例來看看需求列表是怎樣編寫的吧。這是一個公司內部的評審系統,它分爲制訂評審計劃、執行評審、製作評審報告與問題跟蹤四部分。經過初次與評審人員的業務討論以後,我們整理出這樣一個需求列表:

1.評審發起人填寫一份評審計劃,詳細記錄評審時間、評審內容、評審者、評審地點,制訂評審組長,並預計評審工作量,發起一個評審任務。
2.評審者在收到郵件後,進入評審任務中,對評審內容進行評審,同時填寫並提交各自的評審意見。
3.評審組長彙總所有的評審意見,並在評審會上依次過所有的評審意見,對評審意見進行修改或刪除,填寫問題跟蹤,形成此次評審會上最終的評審意見及問題跟蹤表。
4.評審組長製作評審報告,並形成評審結論,以郵件的形式通知所有評審者。
5.所有評審者對評審報告進行回覆意見,如果都選擇同意,評審組長關閉此次評審。
6.評審組長跟蹤所有問題,並可以依次關閉每個問題。

當然,在這個需求列表中,客戶提出了一些名詞,比如評審計劃、評審意見、評審組長等。我們在整理需求列表的同時,應當注意整理這些名稱,弄清它的內涵外延,以及它們相互之間的關係、作用。這將爲我們後面的領域模型分析提供素材。毫無疑問,這樣的需求列表過於粗略。因而在後面的業務討論中,我們逐項對它們進行了細化:

1.評審發起人填寫一份評審計劃,詳細記錄評審時間、評審內容、評審者、評審地點,制訂評審組長,並預計評審工作量,發起一個評審任務。
1.1 評審時間應當分爲數個階段分別制訂時間計劃,如評審準備、評審會議、評審報告;
1.2 評審內容應當可以上傳數個文件,分別描述文件的內容、作者、編寫日期、版本號,供評審者下載與查看;
1.3 填寫評審者時,選擇一個評審者爲評審組長,評審發起人不能是評審組長;
1.4 評審地點與預計評審工作量只需直接填寫;

在我們後面的用例分析中,我們對這段需求列表進行了大量的分析設計。但這些都是設計與實現,它們會出現在後面的用例分析及其模型中,卻不應出現在需求列表中。在後來的升級開發中,客戶又提出了發郵件通知的功能。將該功能描述出來,並添加到需求列表中:

1.5 評審計劃提交以後,以郵件的形式發送給每個評審者,通知該評審任務。

有了這樣的需求列表,當需求分析工作完成時,我們將一項一項檢查用例模型是否滿足需求列表的內容;當軟件開發完成時,我們將一項一項檢查軟件功能是否滿足需求列表的內容;當用戶驗收時,我們同樣使用需求列表,一項一項檢查我們的軟件是否滿足用戶需求。


我們應當怎樣做需求確認:快速原型法

常常聽到許多朋友跟我埋怨,需求分析之難,就在於用戶自身就常常弄不清楚自己的需求。起初在需求確認的時候說得好好的,一到軟件上線的時候就不是那麼回事了,這可沒法整。但我們只要坐下來仔細分析就會發現,在需求分析的時候我們跟用戶是在空對空地討論問題。用戶不是專業人士,他也搞不清楚軟件到底會做成啥樣,所以你跟他確認的時候他就點頭了。但是,用戶不是傻子,當你軟件上線時,他拿到了實物了,知道軟件做成啥樣了,一旦不滿意他就開始提變更了。所以,需求分析的癥結就在與這個實物。

既然癥結在此,毫無疑問,我們就應當在需求分析階段拿出實物,用實物與用戶確認需求,這就是快速原型法的基本思想。快速原型法,簡稱原型法(Prototyping),是20世紀80年代提出的一種從設計思想、工具、手段都全新的系統開發方法。它摒棄了那種一步步周密細緻地調查分析,然後逐步整理出文字檔案,設計開發,最後才能讓用戶看到軟件結果的繁瑣作法。當我們捕獲了一批業務需求以後,就立即使用快速可視化工具開發出一個原型,交給用戶去試用、補充和修改。再提出一些新的需求以後,再開發一版新的原型。原型法的關鍵就是這個快速開發。不用考慮性能、美觀、可靠,原型的目的就是模擬客戶的需求,與客戶進行確認的。整個需求分析的過程就是“捕獲需求->原型開發->確認需求->再捕獲需求”的過程。

原型開發的快速與模擬到什麼程度,是一對矛盾,我們要去把握。要快速開發,必然不可能和最終交付的軟件系統一模一樣,許多複雜問題被簡化,非關鍵性流程被忽略,這就是所謂的模擬。因此,模擬到什麼程度是關鍵,既能說明問題,又不耽誤時間。根據我的經驗,一般能拿出界面,並可以走通關鍵性流程就可以了。一些快速開發平臺爲快速原型法提供了可能。

當用戶拿到原型可以自己操作時,需求研討的氣氛立即變得不太一樣了。當用戶享受原型給他們帶來體驗的快感時,需求被源源不斷地被提出來。這時候的需求,就不再是枯燥無味的文字遊戲,而是生動形象的圖形界面。日後,如果項目採用迭代開發,讓用戶看着軟件一點兒一點兒地成長,這又是多麼美妙的體驗啊。與此同時,你與用戶的信任也在一步一步建立起來,軟件風險在降低,項目將朝着正確方向前進。

快速原型法是美妙的,它給你與用戶帶來了從未有過的體驗。但美妙的同時,也會帶來一些的尷尬,不必要的誤會,我們一定要注意。最常見的誤會就是讓用戶將原型誤以爲最終交付的系統。開發一個系統需要持續數月,但你倒好,幾天就搞定了,爲什麼還要在這個系統上投入大量資金呢?如果對方領導開始有這樣的想法時,雙方就開發費用進行的談判就有一些不妙了。所以在給用戶看到原型前,一定要跟用戶解釋清楚。

既然是原型,必要的校驗、非正常操作的處理通通都被忽略。因此,當演示原型出錯時,用戶你可千萬不要較真喲!這醜話可得說在前頭,否則用戶跟你較起真來,你在用戶心目中的形象可就要大打折扣了。

總之,根據實際情況靈活運用原型法,可以更加順暢地與用戶確認需求。甚至在最後編寫需求規格說明書的時候,都可以將原型的截圖放進去。都是與用戶確認好的東西,又能提高需求規格說明書的準確與生動,何樂而不爲呢?


我們應當怎樣做需求確認:需求規格說明書

曾經有項目組拿着用戶編寫的原始需求就開始開發,隨後狀況不斷,一次令人崩潰的研發過程。拿着用戶編寫的原始需求,編寫我們自己的需求規格說明書,之所以重要,就在於用戶編寫的原始需求,是脫離了技術實現,編寫的一份十分理想的業務需求。理想與現實總是有差距,我們之所以要編寫自己的需求規格說明書,就是要本着實事求是、切實可行的態度,去描述用戶的業務需求。那些不可行的需求被摒棄,或者換成更加可行的解決方案。這就是需求規格說明書的重要作用。

從理論上講,需求規格說明書(Requirement Specification)分爲用戶需求規格說明書和產品需求規格說明書。用戶需求規格說明書是站在用戶角度描述的系統業務需求,是用於與用戶簽字確認業務需求;產品需求規格說明書是站在開發人員角度描述的系統業務需求,是指導開發人員完成設計與開發的技術性文檔。但是,我認爲,用戶需求規格說明書與產品需求規格說明書的差別並不大。領域驅動設計所提倡的就是要讓用戶、需求分析員、開發人員站在一個平臺,使用統一的語言(一種混合語言),來表達大家都清楚明白的概念。從這個角度將,需求規格說明書就應當是一個,不區分用戶需求規格說明書和產品需求規格說明書。

那麼需求規格說明書怎麼寫呢?不同的公司、不同的人、不同的項目,特別是在需求分析中採用不同的方法,寫出來的需求規格說明書格式都是不一樣的。在這裏,我給大家一個,採用RUP統一建模的方式分析需求,編寫需求規格說明書的模板,供大家參考。

1.引言
1.1 編寫目的
如題,描述你編寫這篇文檔的目的和作用。但最關鍵的是,詳細說明哪些人可以使用這篇文檔,做什麼。需求規格說明書是用來做什麼的?毫無疑問,首先供用戶與開發公司確認軟件開發的業務需求、功能範圍。其次呢,當然就是指導設計與開發人員設計開發系統。當然,還包括測試人員設計測試,技服人員編寫用戶手冊,以及其它相關人員熟悉系統。描述這些,可以幫助讀者確定,閱讀這篇文檔是否可以從中獲得幫助。

1.2 業務背景
描述業務背景,是爲了讀者瞭解與該文檔相關的人與事。你可以羅列與文檔相關的各種事件,也可以描寫與項目相關的企業現狀、問題分析與解決思路,以及觸發開發該項目的大背景、政策法規,等等。

1.3 項目目標(或任務概述)
就是項目能爲用戶帶來什麼利益,解決用戶什麼問題,或者說怎樣纔算項目成功。前面提到過,這部分對項目成功作用巨大。

1.4 參考資料
參考資料的名稱、作者、版本、編寫日期。

1.5 名詞定義
沒啥可說的,就是文檔中可能使用的各種術語或名詞的定義與約定,大家可以根據需要刪減。

2.整體概述
這部分是對系統整體框架性地進行描述。

2.1 整體流程分析
繪製的整體行動圖,及其對它的說明。

2.2 整體用例分析
繪製的整體用例圖,以及對每個用例的用例說明。如果項目比較大,存在多個子系統,可以將用例圖改爲構件圖,詳細描述每個子系統及其相互的接口調用。

2.3 角色分析
一個用例圖,描述系統中所有的角色及其相互關係。在隨後的說明中,詳細說明每個角色的定義及其作用。

這部分還可以根據項目需要編寫其它的內容,如部署方案、網絡設備、功能結構、軟件架構、關鍵點難點技術方案,等等。

3.功能需求
3.1 功能模塊(子系統)
一個一個描述系統中的每個功能模塊(或子系統),即整體用例分析中的每個用例。這部分是需求規格說明書最主要的部分。

3.1.1 用例圖
繪製該模塊的用例圖(詳見《功能角色分析與用例圖》)。

3.1.2 用例說明
對用例圖中的每個用例編寫用例說明(詳見《用例說明》)。

3.1.3 領域模型
爲用例繪製領域模型,並編寫領域模型說明,對每個實體進行說明。對實體的說明包括對實體的定義、屬性說明、行爲說明、實體關係說明等等。如果實體間關係複雜,還要使用對象圖說明實體關係的所有情況(如《領域驅動設計》中的描述)。

4.非功能需求
這裏描述的是軟件對非功能需求的一般要求,即整體設計原則。那些與具體功能相關的非功能需求應該放在用例說明的“非功能需求”部分(詳見《非功能需求》)。

5.接口需求
如果項目涉及到與外部系統的接口,則編寫這部分需求。
5.1 接口方案
詳細描述採用什麼體系結構與外部系統的接口。
5.2 接口定義
接口的中文名、英文名、功能描述、參數、返回值、使用者、使用頻率,等等。


我們應當怎樣做需求確認:評審與簽字確認會

時間過得真快,經過一系列需求研討、需求分析和整理確認,我們整理出了需求列表,編寫出了需求規格說明書,一切似乎該到結束需求分析階段的時候了。但是,敏捷大師的一句話讓我們徹底心涼到了骨頭裏。敏捷大師說了,我們不可能在需求分析階段完成所有的需求分析工作,它將延續到設計、開發,甚至測試階段。

一直以來,我對這句話非常困惑。既然需求分析階段不能完成所有的需求分析工作,那麼完成多少纔算結束呢?80%?60%?或者更少?大師沒有給出一個標準。大師就是大師,生活在太空裏的,我們慢慢理解吧。經過多年的實踐,我慢慢理解了。我們說這種需求分析工作不可能完全完成,或者說日後用戶的需求會變,其實並不是毫無規律可循的。通常,用戶對需求的變更只發生在某些固定的範圍內,弄清楚了這些範圍,我們的問題就迎刃而解了。

1. 整體需求不變,具體細節變化。我們說需求是分層次的,整體框架、功能模塊、每個操作的細節。如果用戶變更到了將整個框架都推翻了,這個項目就別做了。所以整體框架是必須在需求分析階段完成的,是日後不可能改變的。功能模塊可能要變,但通常是某個部分在變,而更多的是那些具體操作的細節在變。

2.  界面風格與操作易用性是最容易發生變更的。我們說用戶看到軟件以後不滿意,其實主要是對界面風格與操作性不滿意,而不是軟件功能。界面不夠美觀,操作不方便,不符合用戶的操作習慣,都是造成用戶不滿意的地方。

3.  增加其它功能。軟件是對現實的模擬,而現實也是複雜多變的。我們與用戶在進行業務流程分析時,也許一些流程沒有考慮到,或者還有特殊情況需要處理。這些是客戶要求增加功能的主要動因。

經過以上分析,需求分析階段要做到什麼程度就可以清楚了:整體框架與功能模塊必須確定下來,至於各個功能模塊下的具體操作,儘量做,能到什麼程度先到什麼程度。至於界面風格與操作性,我們可以在日後迭代開發的每個迭代期,拿出樣品以後再與用戶確認。

OK,萬事俱備只欠東風,當所有工作都完備以後,我們的需求分析工作開始進入最後收尾的階段。我們說,需求分析階段的產出物是需求列表與需求規格說明書,而最終結束的里程碑無疑就是需求評審會了,或者說與用戶的簽字確認會。

需求評審會的主要目的就是確認需求,以便以此開始我們的設計開發工作。從理論上說,需求評審會應當由用戶代表,與項目經理、需求分析員、系統架構師、設計人員、測試人員、QA經理,還有公司相關領導參加。但實際上,讓如此多不同角色的人聚集在一起開會是不現實的。因此,我們可以將需求評審會分爲內部評審會與外部評審會兩部分來開比較現實。

處理外部問題,必先要從內部統一思想。先召開一個內部評審會,聽聽系統架構師、設計人員、測試人員、QA經理對需求分析工作的意見,然後由領導講講話,佈置一下後面的工作,是十分有必要的。按照我的經驗,系統架構師這時的作用相當重要,他應當仔細閱讀需求,仔細思考技術是否可行,以及預測該系統是否能夠達到用戶方領導對該項目制訂的目標。如果答案是否定,立即進行調整。

最後就是與用戶的外部需求評審會了。外部需求評審會,也可稱爲簽字確認會議,就是與用戶就需求規格說明書進行評審,最後簽字確認。用戶簽過字的東西,不可能完全抑制住用戶的變更,但至少從很大程度上抑制住了用戶的大改。然而,在召開外部需求評審會之前,我們建議大家就需求規格說明書,先與各個單位或部門的用戶代表討論並確定下來,避免在最終的簽字確認會上出現分歧,影響工作進度。畢竟大家都不容易,工作一大堆,聚在一起不容易。

經過數月的分析討論,最終在一片和諧的氣氛中,雙方領導在需求規格說明書上簽字,項目開始進入一個新的輪迴。在這個輪迴中,是焦頭爛額、不勝其苦,還是如履薄冰、最終順利交付,是與許多因素有關的。但我想說,一份高質量的需求分析必定起到決定性的作用,必定爲日後的軟件開發掃清了許多許多的地雷


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章