1. 程式人生 > >《軟體方法(上)》讀書筆記

《軟體方法(上)》讀書筆記

1、建模

1.1、業務建模之願景

重點1:通俗一點講,一個東西的願景就是:東西最應該賣個誰,對他有什麼好處?

重點2:願景是需求排序的主要依據。

重點3:老大、願景、需求都是基於現狀尋找最值得的改進。改進過後,又是新的現狀了,還是基於現狀尋找最值得的改進。進一步說也可以說,需求只有真假對錯,沒有變化。說需求有變化,那是從一個靜止時間點來看的。

1.1.1、願景


建模之願景

1.2、業務建模之業務用例圖

有了願景,我們知道老大對他所代表的組織的現狀的某些指標不滿意。接下來就可以研究組織,弄清楚到底是組織的哪些環節造成了這些指標比較差,這就是業務建模(Business modeling)的主要內容。

重點1:軟體系統只是組織的一個零件。組織裡面還有很多系統,其中最值錢的是千百年來一直在使用,現在依然是最複雜的系統——人腦系統。

重點2:開發團隊發現需求“容易變化”。根源之一是需求的來路不正,沒有把系統當作一個零件放在組織中來看,靠拍腦袋得出需求,導致得到的系統需求是錯的。

1.2.1、業務角色

① 業務執行者

以某組織為研究物件,在組織之外和組織互動的其他組織(人群或機構)就是該組織的執行者。以一家商業銀行為研究物件,觀察在它邊界之外和它打交道的人群或機構,可以看到儲戶來存錢,企業來貸款,人民銀行要它作監督等等,這些就是該商業銀行的執行者,如下圖所示:


業務執行者(一)

這裡要注意的是,作為觀察者的建模人員本身是一個人腦系統,所以在觀察組織邊界時,直覺上觀察到的不是組織之間的互動,而是組織派出的系統之間的互動,但是一定要把它理解成組織間的互動,因為談論業務執行者時,研究物件是組織,所以外部對應物——業務執行者也應該是組織。例如:以某國稅局為研究物件,可以觀察到企業財務人員到國稅局報稅,但業務執行者不是企業財務人員,而是企業。也許到後來,企業財務人員和國稅系統互動,又或許再後來是企業系統與國稅系統互動,從組織的抽象級別來看,都應該理解為企業和國稅局這兩個機構之間的互動,如下圖所示:


業務執行者(二)

② 業務工人

組織內的人稱為業務工人,例如某商業銀行裡面的營業員。業務工人是可以被替換的人腦零件,它可能被其他業務工人替換,但更有可能被業務實體替換。

③ 業務實體

業務實體是組織中的非人智慧系統,例如銀行的ATM、點鈔機、營業系統。

1.2.2、識別業務用例

重點1:業務用例指業務執行者希望通過和所研究組織互動獲得的價值。業務用例是組織的價值,不會因為某個人腦系統或電腦系統的存在或消失而改變,好比如300年前的商業銀行和當前的銀行的業務用例是不變的,因為銀行提供價值的本質沒有改變。所以“這個系統的業務用例是什麼”這樣的說法是錯誤的。

重點1:用好用例,關鍵在於理解“價值”。價值是期望和承諾的平衡點、買賣的平衡點。例如以“醫院”為研究物件,真正的用例是“患者→看病”,而不是“患者→掛號”,患者→掛號”可以是以“掛號室”為研究物件的業務用例(如下圖)。所以做任何事情之前,要搞清楚“邊界”,沒有邊界會很容易盲目“拍腦袋”做一些努力但沒效果的事情。


業務用例識別

1.2.2.1、識別業務用例思路

識別業務用例的思路有兩條:

【從外到內】從業務執行者開始考慮,思考業務執行者和組織互動的目的(主要);

【從內到外】通過觀察組織的內部活動,一直問為什麼,向外推匯出組織外部的某個業務執行者(補漏)。


業務用例識別思路

1.2.2.1.1、識別業務用例常犯錯誤

錯誤1 :把業務工人的行為當做業務用例。


錯誤用例識別(1)

錯誤2:業務用例隨待引入系統伸縮。


錯誤用例識別(2)

錯誤3:把害怕遺漏掉的擴充套件路徑片段提升為業務用例。


錯誤用例識別(3)

錯誤4:管理型業務用例。


錯誤用例識別(4)

總結:錯誤的根源主要源於:建模人員分不清問題和問題的解決方案。

1.3、業務建模之業務序列圖

1.3.1、描述業務流程的手段

本章節主要討論的是業務建模中最繁重的工作——描述業務用例的實現,即業務流程,然後改進它,推匯出待引入系統的用例。目前描述業務流程的可選擇手段有文字、活動圖和序列圖,它們的主要區別如下(以財務部“員工→報銷”用例的實現為樣例):

● 文字


文字樣例

文字的缺點是不夠生動,所以在描述業務流程時很少使用文字方式。不過,描述系統用例(即系統需求)的流程時,文字是常用的,因為此時更注重精確,而且還要表達業務規則、效能等目前尚未被UML標準覆蓋的內容。

● 活動圖


活動圖樣例

序列圖是UML圖形描述業務流程的兩種選擇之一。活動圖的前身是流程圖,應該是在建模人員中使用頻率最高的圖形,是隨機械工程領域慢慢引入到計算機領域。不過,隨著程式語言表達能力越來越強,針對簡單的分支或迴圈邏輯畫圖在很多情況下已經變得沒有必要。

● 序列圖


序列圖樣例

序列圖與活動圖的比較如下:

1)活動圖只關注人,序列圖把人當作系統;

在上一章節中已經提到,現在的業務流程中已經有很多領域邏輯是封裝在業務實體而不是業務工人中,如果忽略非人智慧系統,很多重要資訊就丟掉了。

2)活動圖表示動作,序列圖強迫思考動作背後的目的;

序列圖可以更加清晰地表述業務工人或業務實體對外的責任,也就是用例的期望值。期望和承諾是用例和物件技術的關鍵思想,使用序列圖來做業務建模,“物件協作以完成用例”的思想就可以統一地慣竊業務建模和系統建模的始終。

3)活動圖“靈活”,序列圖“不靈活”;

不少人認為活動圖勝過序列圖的地方是它靈活,但這靈活是一把雙刃劍。活動圖很靈活,他的控制箭頭可以指向任何地方,就像編碼原始時代的“goto”語句,所以活動圖很容易畫。不過,“很容易畫”的活動圖也比較容易掩蓋建模人員對業務流程認識不足或者業務流程本身存在缺陷的事實。序列圖可通過alt、loop等結構化控制片段來描述業務流程,強迫建模人員用這種方式思考。

1.3.2、業務序列圖要點

1.3.2.1、訊息代表責任分配而不是資料流動

序列圖中最重要的要點是訊息的含義。A指向B的訊息,代表“A請求B做某事”,或者“A呼叫B做某事的服務”,而“做某事”是B的一個責任。


序列圖訊息含義

1.3.2.2、抽象級別是系統之間的協作

業務建模的研究物件是組織,出現在業務序列圖生命線上的物件,其最小顆粒是系統,包括人和非人系統,而系統之間最主要突出的是協作。所以“系統粒度”和“協作”是業務序列圖的關鍵要點,如果記住了這兩個關鍵點,就可以避免了對組織物件抽象的錯誤以及對協作理解的錯誤。


系統內部的元件暴露
表達了過細的互動步驟

以上說的兩種錯誤是把需求和分析的工作流的工作帶入了業務建模。第一樣例圖提到的系統內部的元件,應該在分析和設計工作流中描述;第二樣例圖提到了互動步驟,應該在需求工作流中描述。除了以上兩種抽象級別的錯誤,還有一種是:業務序列圖的內容和業務用例圖差不多,如下所示:


目標組織作為整體出現在業務序列圖中  

1.3.2.3、把時間看作特殊的業務實體

業務序列圖中,我們把時間看作特殊的業務實體。把時間看作上帝造好掛在天上的一個大鐘,向全世界各種系統傳送時間訊息,這樣,就和後面需要工作流中對映系統用例的時間執行者一致了,同時也幫助理清什麼情況下使用時間執行者的問題。


把時間當作一個系統

值得注意的一點是,時間和定時器不是一個概念,時間是“外系統”,定時器是其他系統用來和時間打交道的“邊界類”。世界上只有一個時間系統,但有無數的定時器。如果建模人員在識別系統用例時說“執行者是定時器”,那就錯了,執行者是時間。


時間和定時器的區別

1.3.2.4、為業務物件分配合適的責任

分配給業務物件的責任必須是該物件有能力承擔的,這需要我們自身必須對理解要十分清晰,畢竟我們自己說話有時候的會含糊。例如“工作人員用Word寫標書”這樣的說法好像可以接受,但如果按照說話的文字不假思索地隨便畫,會很容易導致物件責任分配不準確。


不恰當與不恰當的責任分配對比

1.3.3、現狀業務序列圖

業務序列圖描述的是業務流程,建模需要通過在現狀的業務序列圖基礎上找出改進的要點。如果要把現狀序列圖畫出來,就必須讓自己站在客觀的角度“親臨現場”,“如實”地把所看到的記錄下來,盡力描繪出真實的現狀。但說起來非常簡單,做到卻極其困難。總結到這裡,忽然讓我想起了彼得·德魯克。下面列出一些描述現狀時經常犯的錯誤。

1)錯誤:把想象中的改進當成現狀

很多時候造成這種錯誤,背後的原因很可能是根本沒有深入到組織流程中去做觀察和訪談,對現狀沒有認識,只好想像一個改進後的場景來應付。

2)錯誤:把“現狀”誤解為“純手工”

有的建模人員以為人做的事情才是本質,所以他畫的業務流程中,只有人,沒有非人系統,完全忽略了在技術進步下慢慢可以替代人的這些“業務實體”。

3)錯誤:把“現狀”誤解為“本開發團隊未參與之前”

開發團隊很容易會誤以為當他們開始參與組織流程完善而開發系統的時候當作“現狀”,這就是典型的“技術思維”,很多時候在開發團隊在參與組織流程完善前,組織已經經過了許多次“非系統級”的流程改進,這是站在組織角度去看問題的。

4)錯誤:把“現狀”誤解為“規範”

建模人員在建模業務流程時,照搬組織制定的規範,沒有去觀察實際工作中人們是如何做的,或者即使觀察到了人們實際沒有按照規範做,卻依然按照規範建模。這樣做,得到的業務流程是不真實的,畢竟上有政策,下有對策。

5)錯誤:“我是創新,沒有現狀”

網際網路創業公司的建模人員很容易犯的這個錯誤,動不動就說“我做的是網際網路創新,沒有現狀”,但他們已經忘記了歷史上所有的創新都是站在前輩這些巨人的肩膀之上這個事實。

6)錯誤:“我做產品,沒有現狀”

非定製系統的開發團隊程序拿這句話做介面。A公司的流程和B公司的流程有差異,中國的流程和外國的流程有差異,畫誰的現狀好的?問這個問題的時候,我想是開始開發團隊忘記了“做需求時把產品當專案做”的道理,在第2章節中也提到過“誰比誰更像”的重點。

1.3.4、改進業務序列圖

上面提到的現狀業務序列圖是對組織現狀的客觀描述,而改進業務序列圖是通過資訊化手段去思考對業務現狀序列圖的一些改進。通常,資訊化給人類的工作和生活帶來的改進有三種模式。

1.3.4.1、改進模式一:物流變成資訊流

和資訊的光電運輸比起來,用其他手段運輸的物的流轉速度就顯得太慢了,而且運輸成本會隨著距離的增加而明顯增加。如果同類物的不同例項之間可以相互取代,那麼可以提煉物中包含的部分或全部有價值的資訊,在需要發生物流的地方,改為通過軟體系統互動資訊,需要物的時候再將資訊變成物,這樣就可以大大增加流轉速度和降低流轉成本。


物流變成資訊流改進

1.3.4.2、改進模式二:改善資訊流轉

軟體系統越來越多,而各個軟體系統之間溝通不暢,導致一個人為了達到某個目的可能需要和多個軟體系統打交道,如果把各軟體系統之間的協調工作改為一個軟體系統來完成,人只需要和單個軟體系統打交道,資訊的流轉就改進了。


改善資訊流轉

1.3.4.3、改進模式三:封裝領域邏輯

在業務流程中,有很多步驟是由人腦來判斷和計算的,領域邏輯封裝在人腦中。相對於計算機,人腦(業務人才)存在成本高,狀態不穩定、會徇私舞弊等問題。如果能夠提煉人腦中封裝的領域邏輯,改為封裝到軟體系統中,用軟體系統代替人腦,業務流程就得到了改進。換句話說,領域邏輯的封裝是對系統“內在”價值的提升,相對於前兩個改進模式有更高的要求和更大的困難。


封裝領域邏輯改進

1.3.4.4、改進思考方式:阿布林思考法

在軟體開發團隊中,當有人提出新的想法時,經常會被馬上否定“太難了,做不了”,最終得到一個平庸的、毫無競爭力的系統。學會像阿布(俄羅斯大富豪羅曼·阿布拉莫維奇)一樣思考,有助於克服普通人因資源受限而不敢展開想象的思維障礙。阿布思考法分兩步:

1)假設有充足的資源去解決問題,得到一個完美的方案;

2)用手上現有的資源去山寨這個完美的方案。

其實,阿布思考法的核心思想就是,不要閉門造車,要“接地氣”的行動起來,主動去觀察,或主動尋找有用的資訊去分析和調研,不要被各種侷限被迫讓步。

2、需求

2.1、需求之系統用例圖

在“建模”階段我們研究和思考的物件是組織,從組織的整體性客觀地去發現組織如何可以通過資訊化手段去優化流程。有了客觀的整體性分析和改進認知,接下來的“需求”階段需要深入到系統層面去思考了。按正常邏輯,每一步都有“承上啟下”的作用,本章節所研究的系統用例就是通過上一步業務序列圖中所映射出來的。

執行者和用例的概念在業務建模的學習中已經出現過,現在要研究的執行者和用例與業務建模時研究的執行者和用例相比,不同之處是研究物件,之前研究的是組織,現在研究的是系統。

2.1.1、系統執行者要點

系統執行者的定義:在所研究系統外,與該系統發生功能性互動的其他系統。

2.1.1.1、系統是能獨立對外提供服務的整體

封裝了自身的資料和行為,能獨立對外提供服務的東西才能稱為系統。不瞭解這點,建模人員很容易把“新增一些功能”當作“研發新系統”。


劃分系統用例

2.1.1.2、系統邊界是責任的邊界

系統執行者不是所研究系統的一部分,是該系統邊界外的另一個系統。這裡的系統邊界不是物理的邊界,而是責任的邊界。


錯誤的遙控軟體用例圖    
正確的遙控軟體用例圖

 

2.1.1.3、系統執行者和系統有互動

外系統必須和系統有互動,否則不能算是系統的執行者。如一名旅客來到火車站售票視窗,告訴售票員目的地和車次,售票員使用售票系統幫助旅客購買火車票,這個場景中,和火車票系統互動的是售票員,他是售票系統的執行者。


旅客不是售票系統的執行者

如果火車售票系統現在已經提供了旅客自行購票的介面,例如網際網路購票、售票機等,這種情況下,旅客也是售票系統的執行者。不過“售票員→售票”和“旅客→購票”是兩個不同的用例。

2.1.1.4、互動是功能性互動

上面說的互動還引出一個問題:假設售票員使用滑鼠和售票系統互動,按道理,比起銷售員,滑鼠裡售票系統更近,為什麼不把滑鼠作為售票系統的執行者呢?還有,假設售票系統執行在Windows作業系統之上,那麼Windows是不是售票系統的執行者?其實吧,辨別這些問題的要點就是:執行者和系統發生的互動是系統的功能需求。滑鼠和作業系統跟售票系統的互動都不是售票系統的核心域概念。售票員和售票系統之間的互動才是,所以售票員才是售票系統的執行者。


售票系統的功能需求

2.1.1.5、系統執行者可以是人或非人系統

系統執行者可以是一個人腦系統,也可以是一個非人智慧系統,甚至是一個特別的系統——時間。在軟體業的早期,一個系統的執行者往往全部都是人。隨著時間的推移,系統的執行者中非人執行者所佔的比例越來越多。用例的優勢在於“執行者”和“涉眾”的概念,把演員和觀眾分開。演員(執行者)在臺上表演,觀眾(涉眾)在臺下看,演員表演什麼是由觀眾的口味決定的,演員可以不是人,但觀眾肯定是人。演員如果是人類,那麼在觀眾席上也會有一個位置,不過在第幾排就不知道了(權重等級)。用例使用“執行者”和“涉眾”代替了原來的“使用者”是一個非常大的突破,建模人員如果過多地關注“使用者”,混淆了真正真正重要的前排“涉眾”的需求,把操作人員當前重要的調研物件(非關鍵人員),那麼花在重要的前排涉眾(關鍵人)身上的時間可能就不夠了。越來越多的系統執行者不是人類,也就是說沒有“使用者”。


從“執行者都是人”到“執行者有一些是人”

 

2.1.1、識別系統執行者

2.1.2.1、從業務序列圖對映系統執行者

如果沒有做業務建模,識別系統執行者只能靠頭腦風暴。例如:什麼人會使用系統來工作?什麼人負責維護系統?系統需要和哪些其他智慧系統互動?有沒有定時引發的事件?等等問題。有了業務建模,可以直接從業務序列圖對映即可。業務序列圖上,和所研究系統有實線相連的物件對映為所研究系統的執行者。


業務序列圖:需找租客線索  
從業務序列圖對映得到系統執行者

 

2.1.3、系統用例要點

2.1.3.1、價值的買賣的平衡點

系統用例的定義:系統能夠為執行者提供的、涉眾可以接受的價值。和業務用例相比,研究物件從組織變成了系統,要理解好系統用例,重點依然是之前所強調的買賣平衡點、期望和承諾平衡點。

用例之前的許多需求方法學,把需求定義為思考系統“做什麼”,用例把需求提升到思考系統“賣什麼”的高度。這種思考是非常艱難的,因為它沒有標準答案,只有最佳答案。要得到這個答案,不能靠拍腦袋,必須揣摩涉眾。要得到合適的用例,需要有一顆善於提擦他人的心。


ATM和程式設計師人腦系統的用例

2.1.3.2、價值不等於可以這樣做

有些人會較真,還是以ATM為例子,有些人會因為“難道ATM放在那裡我就不能登入一下就離開嗎?我今晚下班就去ATM那裡登入一下給你看,然後走人。”ATM確實能登入,但登入功能並非ATM的賣點,如果以一個“門禁系統”為研究物件,登入就可以作為它的用例。

還有一種情況,例如科員可以有A和B用例,科長因為比科員的權力大,所以就能擁有科員的用例。用例的執行者只是表明這個用例是為這一類執行者而做的。但不代表系統一定要有許可權控制以防止其他的人或電腦系統使用該用例。即時系統確實需要有許可權控制,而且角色的劃分和執行者相近,也要把這兩者分開,更不可以因為系統不設許可權控制,所以把執行者的名字合併為“使用者”。


用例劃分案例

有些書中會給出“最佳粒度原則”。例如:一個系統的用例最好控制在XXX個之內,一個用例的基本路徑最好控制在X步到X步之間……這些是沒有根據的。市場需要各種各樣的系統,有功能眾多的,也有功能單一的,也有交付複雜的,應該把屁股坐到涉眾那邊去,揣摩涉眾的心裡,實事求是地寫下來。如果建模人員在粒度問題上激烈爭吵以及糾纏不清,有可能已經犯了錯誤,最常犯的錯誤是把步驟當作用例。


錯誤:把步驟當作用例

2.1.3.3、增刪改查用例的根源是從設計對映需求

有一些用例圖,映入眼簾的用例是四個四個一組的,仔細一看,剛好對應看資料庫的四種操作。相當於把資料庫的各個表名加上新增、刪除、修改、查詢,就得到了用例的名字。有些建模人員確實也知道這個錯誤,但他們學乖了,乾脆把每四個用例合併,改名叫“管理XX”或(“XX管理”),然後新增、刪除、修改、查詢等用例再擴充套件它,可惜依然是換湯不換藥。


從資料庫視角得到的用例

 

2.1.3.4、從設計對映需求錯誤二:“複用”用例

增刪改查用例實際上就是從設計對映需求,導致“複用”用例的一種情況。在看看以下例子:


“複用”用例錯誤示例——缺陷管理系統

從不同的業務序列圖分別對映得到系統有右邊四個用例,但有的建模人員會動起心思:這些實現起來不都是針對“缺陷”表來“select X X X from缺陷表where X X X”嗎,合併成一個用例“查詢缺陷”多好!於是得到左邊的結果。實際上,右邊這四個用例面對的執行者不同,背後的涉眾利益也有差別。

當然,如果真的像這位建模人員講的,把“資料庫”,買回去就好,想怎麼折騰這資訊都可以那不是更加簡單。其實,用例是涉眾願意“購買”的、對系統的一種“用法”,只要涉眾願意“購買”,當然越多越好。講到這裡,就要來說一個需求的基本要點:需求不考慮“複用”,如果考慮“複用”,要警惕自己是不是已經轉換到了設計視角來思考問題。

2.1.3.5、系統用例不存在層次問題

系統用例的研究物件就是某特定系統,不是組織,也不是系統內部的元件。如果存在“層次”上的疑惑,背後的原因是研究物件不知不覺改變了。

像醫院資訊系統的用例,有人會畫成如下圖所示,原因可能是前面沒有畫業務用例圖和業務序列圖,所以建模人員頭腦裡不知不覺把醫院資訊系統的價值和醫院的價值混在一起了。


錯誤的“高層”用例:混淆組織的價值和系統的價值

還有以下的防汛系統用例圖,把系統的願景當成了“高層”用例:


錯誤的“高層”用例:把願景當作用例

以下更為常見的錯誤,為系統的“模組”或“子系統”畫用例圖:


錯誤:模組的用例  
用例仍然是系統的用例    
錯誤:子系統的用例

2.1.3.6、用例的命名是動賓結構

用例的命名是動賓結構,例如“取現金”。動詞前面可以加狀語,賓語前面可以加定語,把一句話的主語砍掉,剩下的可以用作用例的名字。

給用例起名時不要使用弱動詞。用例之前的需求技術,可能是以“名詞+動詞”的形式命名系統的功能,例如“發票作廢”,後來要改成用例的動賓結構了,有的建模人員就在前面加一個弱動詞“進行”,就變成了“進行發票作廢”,這個也是不合適的。

如果“名詞+動詞”已經成為行業中的一個術語,也未必要嚴格的動賓結構,例如“成果分析”是某行業的一個術語,也就不必硬要倒過來變成“分析成果”了。

2.1.4、識別系統用例

2.1.4.1、從業務序列圖對映系統用例

其實,只要認真做好業務建模,從業務序列圖上對映系統用例,得到的結果自然就會符合上面說的這些要點。

從業務序列圖中,從外部指向所研究系統的訊息,可以對映為該系統的用例。現在我們繼續從“識別系統執行者”的用例中結合執行者和系統用例一起識別。


從業務序列圖上找到從外部指向所研究系統的資訊    
從業務序列圖對映得到系統用例

 

在以上業務序列圖中,有一處訊息是“外呼人員”指向“線索管理系統”的訊息為“提供本人當天名單”,但在以上系統用例圖中,用例名改為了“檢視本人當天名單”。因為序列圖上的訊息代表“請求某系統做某事”,用例代表“用某系統來做某事”,一定要理解兩種圖的要點,所以有的地方需要調整。

在以上系統用例圖中,有的箭頭是從執行者指向用例,這樣的執行者稱為用例的主執行者,有的箭頭是從用例指向執行者,這樣的執行者稱為用例的輔執行者。主執行者主動發起用例的互動,輔執行者在互動的過程中被動參與進來。

值得注意一下,輔執行者這個概念是被誤用的比較多。最常見的錯誤是把資訊的接收者或者將來可能使用資訊的人當成輔執行者。另一種輔執行者的誤用剛好相反,把資訊的來源當作輔執行者。


錯誤:把可能會用到所生產資訊的人當作輔執行者  
錯誤:把提供用例所需要資訊的人當作輔執行者

以上錯誤的原因很多是因為前面沒有畫業務序列圖,導致建模人員在畫系統用例圖的時候產生焦慮,總是希望在圖上多放一些資訊,以免自己忘記了。一般來說,輔執行者是非人智慧系統的情況較多,人腦系統作為輔執行者的情況比較少,所以碰到輔執行者是人的時候,要多留心。


正確:合適的輔執行者(因為辦卡需要使用者輸入密碼)

 

2.2、需求之系統用例規約

用例圖表達了用例的目標,但是對於完整的需求來說,這是遠遠不夠的。用例的背後封裝了不同級別的相關需求,我們需要通過書寫用例規約把這些需求表達出來。用例規約就是以用例為核心來組織需求內容的需求規約。用例規約的各項內容可以通過以下類圖來展示:


用例規約的內容

2.2.1、前置條件和後置條件

用例通過前置條件(precondition)、後置條件(postcondition)以契約的形式表達需求。用例相當於系統的一個承諾:在滿足前置條件時開始,按照裡面的路徑步驟走,系統就能達到後置條件。為了避免掉入“從實現角度看這樣可以那樣也可以”的陷阱,後置條件只需要寫出最想要的那個狀態即可。

● 前置條件:用例開始前,系統需要滿足的約束。

● 後置條件:用例成功結束後,系統需要滿足的約束。

2.2.1.1、前置條件、後置條件必須是系統能檢測的


系統必須能檢測前置、後置條件

以上圖為例,“錄入保單”用例的前置條件是錯誤的。業務代表是否已經把保單交給內勤,系統無法檢測,不能作為前置條件;同樣,“收銀”用例的後置條件也是不對的。顧客是否已經帶著貨物離開商店,系統也無法檢測,不能作為後置條件。

2.2.1.2、前置條件必須是用例開始前系統能檢測的


前置條件必須是用例開始前系統能檢測的

 以上圖所示,儲戶開始取現金的互動前,系統不知道儲戶是誰,要去多少錢,所以無法檢測“儲戶賬戶裡有足夠的金額”這個條件。如果把前置條件設定為類似於“存在大於最低限額的現金”這樣的背景條件作為前提條件是可以的。就算很長時間沒人來ATM取現金,這個條件是否成立就擺在那裡。

2.2.1.3、前置後置條件是狀態,不是動作

例如,“經理→批假”的前置條件不能寫“員工提交請假單”,因為是一個動作不是狀態,應改為“存在待審批的請假單”。特別要注意的是,寫成“員工已經提交請假單”很可能也是不對的,因為狀態和導致達到某個狀態的行為不是一一對應的,請假單未必是員工自己提交的,也可以組長負責幫本組人員請假,也可能是從另外的系統批量匯入。

如果分不清狀態和行為的區別,建模就會遇到很大的麻煩。後面的建模工作中,還會不斷討論狀態和行為的問題。

2.2.1.4、前置後置條件要用核心域詞彙描述

“系統正常執行”、“網路連線正常”等放之四海而皆準的約束,和所研究系統沒有特定關係,不需要在前置條件中寫出來,否則會得到一堆沒有任何增值作用的廢話。

後置條件也不能簡單地把用例的名字加上“成功”二字變成“XXX成功”。例如“顧客→下單”的後置條件寫成“顧客已經成功下單”,這不是廢話嗎?更合適的後置條件是“訂單資訊已儲存”。

2.2.1.5、“已登入”不應作為前置條件

“已登入”是一個比較有爭議的情況,以購物網站為研究物件,登入不是用例。這一點已經在前面的已經學習過,那如何處理登入?

1)畫法一:把其他用例作為“登入”的擴充套件


畫法一:把其他用例作為“登入”的擴充套件

 

會員登入後可以下單,也可以檢視以往訂單,還可以退貨……所以上圖這個方法把下單、檢視以往訂單畫出登入的擴充套件。這是錯的。並不是先做A然後做B或C,B和C就成了A的擴充套件。

2)畫法二:把“登入”作為被包含用例


畫法二:把“登入”作為被包含用例

把“登入”變成被其他用例包含(Include)的被包含用例(Include Use Case)。這樣做是正確的。登入用例本來不存在,後來在寫用例規約的時候,發現“下單”、“檢視以往訂單”等用例都有以下步驟:


“檢視以往訂單”步驟

為了節省書寫用例規約的工作量,考慮把這些形成一個小目標的步驟集合(不是單個步驟)分離出來,作為一個被包含用例單獨編寫規約。這個用例只被其他用例包含,不由主執行者指向。所以,如果按照這個做法的話,“下單”用例規約的步驟裡,應該有表示包含“登入”用例的步驟集合:會員【登入】。這裡的“登入”二字加了粗括號表示這是一個被包含用例。它的步驟和約束在另外的地方描述。當然,不喜歡用粗括號可以用下劃線等其他方法以示區分。

3)畫法三:其他用例以“已登入”作為前置條件


畫法三:其他用例以“已登入”作為前置條件

有些人覺得畫法二會讓好些用例會出現會員【登入】,看起來有些礙眼,就想能不能把它提到前置條件裡,那就得到了畫法三。把“登入”作為一個用例,“會員已經登入”作為其他用例的前置條件。這樣用例的步驟看起來更清爽,但是嚴格來說這也是不對的,“登入”不能作為購物網站的用例。

以上章節學習過,如果在做需求時考慮複用,可能已經陷入了設計的思維。能夠在多個用例中複用登入的狀態,這是設計人員的本事,他甚至可以做到10個用例的介面都從一個模板生成,但不能因此就把這10個用例合併成一個。

2.2.2、涉眾利益

前提條件是起點,後置條件是終點,中間的路該怎麼走?這就要由涉眾決定了。也就是我們需要對關鍵人按重要程度排序(從前排到後排)去考慮他們的利益,根據這些利益去梳理正確的需求。以銀行ATM為例子,儲戶在ATM取現金的時,涉及的涉眾利益如如下:

● 儲戶:希望方便;擔心權益受損。

● 銀行負責人:希望安全;希望節約運營成本。

正是這些涉眾利益的交鋒之下,目前我們日常生活中所看到的ATM的用例片段如下:


ATM用例片段

從步驟1有設計約束“通過磁條卡或晶片卡提交賬戶號碼”看,這是為了照顧儲戶“方便”的利益。在銀行角度,雖然儲戶是上帝,為了儲戶更加方便,不用密碼更方便的。但從銀行角度要考慮安全問題,不可能不設定密碼,但為什麼只設置6位而不是8位或者更多呢?這又是“安全”和“方便”交鋒後的妥協……

2.2.2.1、涉眾的來源

1)涉眾來源一:人類執行者

用例的執行者如果是人類,當然是用例的涉眾。執行者如果不是人類,就不是涉眾,因為它沒有利益主張。


考慮人類執行者之後的涉眾

上圖保險系統的“內勤→錄入保單”用例中,內勤是人類,是涉眾,而OA系統不是人類,不是涉眾。

2)涉眾來源二:上游

執行者要使用系統做某個用例,可能會需要一些資源,這些資源的提供者可能就是用例的涉眾。還是以“內勤→錄入保單”為例,保單由業務人員代表提供給內勤。如果內勤喝醉了酒亂錄,資訊錯得一塌糊塗,業務代表的利益就被損害了。所以,考慮到上游之後,“內勤→錄入保單”用例的涉眾有內勤和業務代表了。


考慮上游之後的涉眾

3)涉眾來源三:下游

執行者使用系統做某個用例,產生的後果會影響到其他人。這些受影響的人也是涉眾。還是以“內勤→錄入保單”為例,如果系統做得不好,沒有檢測內勤錄保單時是否填了必填項就放了過去,後面負責稽核的經理工作量增加了。還有,OA系統雖然不是該用例的涉眾,但假如保險系統不停地向OA系統傳送垃圾資料包,導致OA癱瘓,那麼OA系統維護人員的工作量就增加了。所以,OA系統維護人員也是下游的涉眾。考慮下游之後,“內勤→錄入保單”用例的涉眾如下圖所示:


考慮下游之後的涉眾

 

4)涉眾來源四:資訊的主人

用例會用到一些資訊,這些資訊會涉及某些人,雖然這些人也許並不知道這個系統的存在,但他們是用例的涉眾。還是以“內勤→錄入保單”為例,保單的資訊涉及被保人,投保人和受益人,如果資訊出錯或洩露,這些人就會遭殃,所以他們是涉眾。因為這類涉眾可能和系統沒什麼介面,比較容易被忽略,所以要特別需要注意。


考慮資訊的主人之後的涉眾

其實,前面的業務建模對識別涉眾起到了非常大的幫助,如果做需求前做了業務建模,會更加了解一件事情的前因後果,大多數涉眾都能夠從業務序列圖中看出來。如下圖所示:


業務建模可以幫助尋找涉眾

 

2.2.2.2、尋找涉眾利益

查理·芒格說過:說服別人要訴諸利益,而非訴諸理性。所以要學會思考涉眾的利益點是一門非常大的學問。尋找涉眾利益時,要“親兄弟,明算賬”,把不同涉眾各自關注的利益體現出來,而不是寫成一模一樣的。家裡兩夫妻對同一件事情都還有不同立場,更不用說一個組織裡面形形色色的涉眾了。例如,司機開車進廠裝化肥,工作人員通過地磅系統操縱地磅給車稱重。針對這件事,不同的涉眾可謂是“各懷鬼胎”:

● 化肥公司老闆——擔心公司內部人員貪汙;

● 地磅操作員——希望操作簡便;擔心承擔責任;擔心繫統壞掉影響工作量;

● 倉管人員——擔心稱不準導致無謂的返工裝包;

● 買主——擔心進去時稱得輕了,出來時稱得重了,導致給少了化肥;

● 司機——擔心等候時間太長導致每天拉貨次數減少;

即使有些利益有時不方便白紙黑字寫出來共享,但至少建模人員要心知肚明,不能一團和氣了事。建模人員要仔細觀察和揣摩涉眾的痛苦,才能找到真正的涉眾利益,否則寫出來的“涉眾利益”往往很蒼白。例如以下例子:

● 護士——擔心出錯

這都是正確的無用廢話,誰都擔心出錯,但為什麼還是出錯?仔細調研過之後寫出來就生動多了:

● 護士——擔心自己的藥理學知識記錯,對藥物名稱相近的藥物計算錯劑量,導致給藥錯誤;

2.2.2.3、善於積累涉眾利益

需求是不斷變化的,我想這都是共識了,新系統肯定在功能或效能上和舊系統有所不同,否則還做什麼新系統呢。但是,背後的涉眾利益要穩定得多。看看之前ATM的例子出現的涉眾利益:

儲戶——希望方便;擔心權益受損;

銀行負責人——希望安全;希望節約運營成本;

其實這些涉眾利益不止適用於ATM,也適用於清朝的錢莊櫃檯、現在的銀行櫃檯、網上銀行和手機銀行。換句話說,越本質越穩定。

2.2.3、基本路徑

一個用例會有多個場景,其中有一個場景描述了最成功的情況,執行者和系統的互動非常順利,一路綠燈直抵用例的後置條件。這個場景稱為基本路徑。用例把基本路徑分離出來,目的是凸顯用例的核心價值。還是以ATM為例,發生在ATM上的場景有很多:

1)張三來了,插卡,輸入密碼,輸入金額,順順利利取到錢,高興地走了;

2李四來了,插卡,輸密碼,密碼錯,在輸,再錯,再輸,卡被吞掉了;

3王五來了,插卡,輸密碼,輸金額,今天取得太多不能取了……

以上三個場景,只有場景(1)是銀行在大街上擺放一臺ATM的初衷。雖然場景(2)和(3)是難以避免,但場景(1)出現得越多越好,這是涉眾對ATM的期望。

書寫路徑步驟的時候需要注意以下一些要點。這些要點有重疊的地方,如果違反了其中一個要點,很可能會違反另外的要點。

2.2.3.1、按照互動四步曲書寫

執行者和系統按回合互動,直到達成目的。需要的回合數是不定的,可能一個回合足夠,也可能需要多個回合。一個回合中的步驟分為四類:請求、驗證、改變、迴應。如下圖所示:


互動四步曲

在一個回合中,請求是必須的,同時還需要其他三類步驟中的至少一類。看看以下例子,可以看到,第一個回合只需要請求和響應,第二個回合則四類步驟都有。


回合制的互動示例

當時間作為主執行者而且不需要和其他輔執行者互動的用例中,可能會出現不需要回應的情況,而且只有一個回合,如下所示:


回合制的互動示例

在書寫步驟時要注意以下一些形式上的問題:

1)對於時間為主執行者的用例,回合中的請求步驟不寫“時間告知時間週期到了”,而是寫“當到達時間週期時”。

2)驗證步驟不寫“是否”。例如以上例子中,第4步寫“系統驗證註冊資訊充分”,不寫“系統驗證註冊資訊是否充分”,目的是要表達“充分”是基本路徑期望的驗證結果。

3)系統和輔執行者之間的互動可以看作是一種迴應步驟,寫成“系統請求輔助執行者做某事”,例如“系統請求郵件列表系統群發郵件”。

2.2.3.2、只寫系統能感知和承諾的內容

看看以下例子:

……

4、系統反饋應收總金額

5、顧客付款

6、收銀員提交付款方式和金額

7、系統計算找零金額

8、系統反饋找零金額,列印收據

9、收銀員找零

……

顧客付款和收銀員找零是系統無法感知和承諾的。如果寫在步驟裡,會讓人產生誤解:只要用了本系統,顧客就會乖乖付款,收銀員會乖乖找零——也許顧客忘記付款和收銀員忘記找零正式商場要解決的一個頭痛問題。

2.2.3.3、使用主動語句理清責任

把動作的責任人放在主語的位置,看看以下兩句話:

1)伊布從瓦倫西亞處得到傳球,舒梅切爾撲救伊布的射門。

2瓦倫西亞傳球,伊布射門,舒梅切爾撲救。

雖然上面一句比較文藝,但下面一句把責任理得更清晰。用例步驟也是如此:

系統從會員處獲得使用者名稱和密碼(錯)

會員提交使用者名稱和密碼(對)

使用者名稱和密碼被驗證(錯)

系統驗證使用者名稱和密碼(對)

會員要是不提交,就不要怪系統沒有動靜;會員要是提交了,系統不動彈,那就要怪系統了。做到規規矩矩說話,把責任理清楚,其實不容易。再列舉一些常見的“胡說八道”,如下所示:


規矩用詞

2.2.3.4、主語只能是主執行者或系統

寫需求,就是要把系統當作一個黑箱,描述它對外提供的功能以及功能附帶的質量需求。系統如何構造,不屬於需求描述的範圍,除非是涉眾強加的設計約束。所以步驟裡不能出現“執行者請求前端系統做某事,前端系統請求後端系統做某事”“執行者請求客戶端做某事,客戶端請求服務端做某事”“執行者請求A子系統做某事,A子系統請求B子系統做某事”,就算這個系統最終的組成是分解成很多個部分,分佈在一百多個國家執行,需求裡也只有兩個字:系統。前面已經學習過了,系統邊界是責任邊界,而非物理邊界,如下所示:


需求把系統看作是黑箱

 

2.2.3.5、使用核心域術語描述

路徑步驟應該使用核心域的術語來描述,也就是說,要說“人話”。以下以一個零件採購系統為研究物件,比較以下兩句話,哪一句是“人話”,哪一句是“鳥語”?

1)系統建立連線,開啟連線,執行SQL語句,從“零件”表查詢……

2系統根據查詢條件搜尋零件

其實,一眼就能看出,第一句是“鳥語”,第二句是“人話”了。不同職能多少會有主觀意識,做Java開發的覺得自己做的才是技術,需求屬於業務。但需求人員卻覺得自己做的也是技術,他們所研究的客戶才是業務。但客戶覺得自己做的才是技術……,這咋看起來有點像一個鄙視鏈。其實,大家做的都是“技術”,這是領域不同而已。應該用“核心域”和“非核心域”來代替“業務”和“技術”。

如果所研究系統是一個關係資料庫的指令碼工具,核心域是關係資料庫領域,上面提到的“系統建立連線,開啟連線,執行SQL語句”就成了合適的需求。

2.2.3.6、不要涉及介面細節

很多人寫需求的時候,會把介面的細節帶進來,例如:

● 會員從下拉框中選擇類別

● 會員從文字框中輸入查詢條件

● 會員單擊“確定”按鈕

這些介面細節很可能不是需求,更多是設計方案,背後可能隱藏更多的真正需求,也許是可用性需求“操作次數不超過5次”。但畢竟我們面對的客戶各種各樣的喜好都有,可能有些前排涉眾明確要求“一定要用下拉框”,那麼“下拉框”也是需求,但依然不能寫“會員從下拉框框中選擇類別”。因為這裡涉及兩類需求,她們的穩定性和變化趨勢不同,應該分開描述:

● 會員選擇類別(這是步驟)

● 通過下拉框來實現(這是設計約束)

用例的需求組織方式是分層的,從用例的路徑、步驟、約束,穩定性會越來越低,如下所示:


用例規約的需求層級

把需求分層級了,穩定和不穩定的需求就分開了,更有利於瞭解事情的核心本質。平時遇到的大部分“需求變更”發生在補充約束級別,例如輸入會員資訊時加個微信欄位(欄位列表變了),調整結賬時的打折規則(業務規則變了)。級別越高的需求,內容越穩定。

很多時候做需求會把看得見和需求混為一談,真正的需求不見得是顯而易見的。需求判斷的標準不是涉眾是否看得見,而是涉眾是否在意。第一章已經學習過,需求和設計不是一一對應的,而是多對多的。

2.2.3.7、不要涉及互動細節

在步驟中,除了避免描述頁面細節,還要避免描述互動細節。例如有人會這樣寫:

● 會員每輸入賬戶名稱的一個字元

● 系統在介面中驗證當前輸入資訊合法

寫的人有他的道理:系統不是等待提交後才驗證輸入資訊是否合法,而是隨時驗證立即反饋,這樣使使用者體驗更好。其實,這只是互動設計的一些技能。忍不住要在需求規約裡描述介面和互動的細節,背後的原因和忍不住要思考內部程式碼如何實現的原因是一樣的,都是對自己的設計技能沒有信心,害怕“現在想到了如果不忘記記下來以後就忘記了”。這些都是人性的弱點。

用例的步驟應該把焦點放在系統必須接收什麼輸入、系統必須輸出什麼資訊以及系統必須做什麼處理這三個重點上,加上欄位列表、業務規則、可用性需求等約束,足以表達各種需求。

關於用例的互動怎麼寫,是一個比較頭疼的問題。即使不涉及互動設計細節的問題,也免不了混進互動設計的成分,例如,為什麼要分兩個回合而不是一個回合?實際上涉眾更希望一個回合就能達到用例的目標。所以,建議觀點是在用例規約中把路徑步驟刪掉,只保留輸入輸出、涉眾利益和補充約束,互動的路徑步驟由互動設計人員決定。

2.2.3.8、需求是“不這樣不行”

許多需求人員之所以在需求崗位上,並不是因為他掌握了該掌握的需求技能,可能只是因為他工作年限足夠長該換到需求崗位了——和許多年齡到了就上崗的夫妻和父母相似。這樣的需求人員硬著頭皮做需求時,最常用的一招就是託著腦袋想“這個東西是什麼樣子”,然後畫一個介面原型拿去和涉眾確認。一旦涉眾說“差不多就這樣吧”,就把這個介面原型作為需求交給分析設計人員。在這一點上,網際網路公司的產品經理表現得尤為明顯。如果僥倖成功,就拼命鼓吹“原型大法好”,因為他只會這個。

當需求人員問問題時都是“這樣可以嗎”,相當於:

● 需求人員:介面這樣佈局可以嗎?

● 涉   &nbs