1. 程式人生 > >UML分析設計之一需求分析

UML分析設計之一需求分析

1.前言

最近經常聽到一些對於UML質疑的聲音。而我也相信發出這些質疑聲音的人都是親自使用過UML的人。而這幾年在專案中遇到的能夠使用UML作為分析和設計工具的人越來越少。初學UML確實讓人感覺無所適從,而UML作為分析設計的工具又確實不想c/c++,java,.dot net等編成語言那樣直觀,易於應用。子曰:學而時習之,不亦悅乎。學習那些開發語言可以即時看到效果。學UML容易,而想找一個合適的物件來練習就非常困難了。很多人學了UML卻一直用不起來,最後他們得出了UML沒有用的結論。本文是寫給那些想用UML做分析設計的初學者的,以免在UML學習之路上繞太多彎路。

UML是統一建模語言。

UML的作品就是模型。專案中不同階段也需要不同模型來對應。分析階段有分析階段的模型。設計階段有設計階段的模型。兩個模型相互獨立,他們之間也有關聯。比如:奧運會體育館設計首先是選擇整體方案。這個時候我們看到的是鳥巢的模型。而真正施工的時候,當然需要一個更詳細的方案告訴施工單位那裡用什麼樣的鋼結構,跑道用什麼樣的塑膠……軟體開發也是這樣。UML在需求分析階段側重於對需求功能的描述,是描述整個功能。而設計階段是將這些功能分解,告訴程式設計師如何開發。這樣分析和設計的兩個模型就各有不同,有相互關聯。他們之間的關係被稱為精化。

在開始建立模型之前,除了這些基礎知識之外,我們還要選擇一個輔助開發的的工具。我選擇使用的是

Rational公司的Rose。雖然Rational公司被IBM併購,但是IBM後來推出的建模工具並沒有超越古老Rational Rose 2003——雖然新工具號稱支援UML2.x。其他工具可以替代,但是個人用起來又諸多不方便的地方。所以還是用Rose

2.需求說明

我們的原始需求非常簡單,快速的從檔案中讀取資料。因為最近專案中有一個需求是處理程式的日誌。日誌量很大,而我們需要在儘量短的時間內把這些日誌處理完。所以就需要一個快速讀取日誌的工具。

當然,從檔案讀取資料的速度是由硬碟的IO決定的。作為軟體開發者並沒有辦法讓硬碟的磁頭轉的更快。雖然如此,我們確實有辦法讓檔案讀取看起來很快的方法——那就是快取,把一部分資料提前讀取出來,當應用需要處理的時候,從快取裡把資料給應用;而再應用處理資料的時候,我們在後臺讀取更新的資料填充在快取中。

總結一下我們的需求,就是做一個雙緩衝的資料讀取程式。

3.需求分析

使用UML做需求分析也就是對需求建模的過程。UML中建模過程一般都是從用例圖(Use case diagram)開始的。用例圖描述參與者(對系統有影響的外部物件)與用例(系統功能或目標)的關係。

我們的系統目標單一,所以用例圖也很簡單。我們的用例圖如下:


系統目標只有一個——快速讀取資料。

這個圖描述的是一個靜態場景。即呼叫者需要快速讀取資料。接下來我們就是要分析快速讀取資料的過程。這樣一個過程我們需要用動態圖去描述。可以選擇的動態圖有活動圖、時序圖和寫作圖。因為尚不涉及狀態問題,所以沒有必要用狀態圖。個人習慣用活動圖對用例分析,因為活動圖對分支、判斷、迴圈等流程概念的表達比其他圖清晰,適合用於描述業務。

不過開始用活動圖之前,我們需要確定這個過程中大概需要用到那些類。也就是對可能的功能作一個劃分。這也是設計內容的部分。這部分因人而異。從我的角度看,我們需要有一個與呼叫者的介面,用於向呼叫者提供資料;一個讀取資料的介面,用於獲得資料。由於我們要做的是一個緩衝系統,所以還需要一個緩衝器。最後緩衝是在後臺載入的所以還要有一個緩衝的載入執行緒。用這四個物件我們就可以描述快速讀取資料的過程了。

在開始之前我們先準備好這四個類的類圖:


接下來,是活動圖的分析。

圖中灰色部分標出了步驟編號。這一部分是快取中有資料時讀取資料的過程。


Step1: 呼叫者呼叫介面讀取功能。

Step2: 讀取介面從快取中獲取下一個資料。

Step3: 從快取中獲得資料後進行判斷是否為空(null)

Step4: 如果結果不為空則返回結果。

Step5: 呼叫介面將結果返回給呼叫者。

這個分析過程中,我們添加了一個新的類,用來儲存結果的資料類。這個類類圖如下:


這個類是我們分析過程中對我們最初模型的補充。

接下繼續分析快取中沒有資料的時候。


接上圖,活動圖的第二個片段

在快取中獲取的結果為空時,要啟動後臺執行緒載入新的資料。但是自啟動之前要檢查後臺執行緒是否工作,如果後臺執行緒正處於工作狀態,說明上次載入資料的過程沒有完成,要等待他結束。

Step 1: 獲得資料裝載執行緒的狀態。

Step 2: 判斷執行緒狀態。

Step 3: 當執行緒狀態是工作的時候等待裝載執行緒結束。

這個過程中我們也向需求模型中補充了一個新的類——執行緒狀態類,用於儲存執行緒的工作狀態,類圖如下:

 

接下來分析後續過程:


裝載執行緒不活躍的時候,我們要同時做兩件事情,其一是更換緩衝器,其二是讓裝載執行緒開始新的資料裝載過程,將資料新增到剛用完的緩衝中去。

Step 1: 在兩個執行緒中非同步進行。

--將當前緩衝設定為裝載目標,並激活裝載執行緒

--更換介面的讀取設定

Step 2: 判斷緩衝器是否為空。如果為空說明上次裝載資料沒有裝載內容,也就是已經將資源讀完,可以返回空值。

Step 3: 返回空值

Step 4: 如果新緩衝器不為空,重新獲取值。

最後我們分析資料執行緒的活動:


資料裝載執行緒被啟用之後讀取資料。資料裝載結束之後通知等待讀取結束的執行緒繼續,同時自己回到等待狀態。

Step 1: 啟用資料裝載執行緒

Step 2: 一個迴圈載入資料的過程。判斷載入計數器的數值與裝載執行緒額定裝載數量是否相等來結束裝載過程。裝載過程是呼叫資料裝載器載入資源並封裝為結果資料。然後將資料壓入目標緩衝。

Step 3: 緩衝裝載資料達到額定值之後,執行緒回到等待狀態。

Step 4: Step3同時非同步進行,通知等待裝載結束的執行緒繼續執行。

這樣整個資料讀取過程分析結束。

整個活動圖如下:


上圖描述了整個通過非同步的資料裝載執行緒實現快速讀取資料的功能。

在分析中我們也得到了這個過程中涉及的類:


活動圖中,每個類佔用一個泳道,泳道中的活動是這個類在整個過程中所要執行的功能。我們將這些活動和活動中涉及的資料作為成員函式和成員變數新增在我們得到的類模型中。最終類圖如下:


需求分析過程結束。

4.需求分析總結

我們在上面使用UML圖作為展示手段,描述了需求分析的過程。但是使用UML的目的並不在畫圖,而在於建立模型。下滿我們總結模型的結構。

首先:


需求分析模型整體如上圖,我們有一個參與者(呼叫者)和一個用例,在分析過程中得到了六個相關類。

其次:


對用例的活動分析之後我們的到了快速讀取資料過程中涉及的各種活動、狀態和資料。

最後:

 

 

將這些活動、狀態和屬性分配到各個類中,我們就獲得了最終的類結構。

這就是我們的需求模型。