前言
因為之前一直處在游戲開發(fā)行業(yè),由于種種原因一直對軟件工程中的項目管理、項目開發(fā)方法缺乏體驗。雖然項目中也曾倡導編寫更多的文檔,無論是模塊說明文檔還是設計文檔,但效果一直不好。不甚理想的地方主要體現(xiàn)在文檔的規(guī)范性欠缺、不統(tǒng)一、浮于表面沒有實質內容。文檔的編寫缺乏詳盡的方法指導,那么所謂的設計文檔要么是用來敷衍上級要么就是隨著開發(fā)人員的水平不一而千差萬別。
當我開始目前這個非游戲項目時,我也曾想,前期做好結構設計,制定好關鍵問題的解決方案,那么要完成這個項目就不在話下了。但是我很快就面臨了一個問題:需求不定?;叵肷硖幱螒蚬镜哪切┤兆?,程序員總是抱怨策劃需求變更過快過多,在每一次策劃提出一個需求變更時,謹慎的程序員都會再三讓策劃保證:放心,不會變了。而我面臨的問題則更為嚴峻。我意識到,項目的需求,就連用戶也無法一一羅列出來。我們需要的是需求調研。但就算你將客戶的所有需求全部挖掘出來后(這幾乎不可能,因為他們自己也不太清楚自己想要什么),當你交付了第一個軟件版本,幾乎可以肯定客戶會提出一大堆的需求變更:我要的不是這個,我要的那個怎么沒有,哦,我當初以為你說的是另一個意思。
當然,需求調研這種工作不是讓程序員去做的(那會更悲劇,無論是對客戶還是對程序員而言,他們都是在對牛彈琴)。但需求的不確定性也總是存在的。
事實上,需求變化本身就是一個很正常的現(xiàn)象。我一向愿意更悲觀地處理軟件開發(fā)方面的問題,所謂小心使得萬年船?;诖耍覜Q定擺好心態(tài)學學軟件開發(fā)的方法學。
概要
本文簡要描述、總結了RUP開發(fā)方法學的主要內容,結合我自己的感受闡述了一些RUP的核心原則。我相信我所理解的內容是膚淺的,對于非代碼的表達我更相信其是存在歧義的。所以本文僅當是一種經驗參考,不必當真。
RUP據傳是用于指導大型甚至超大型項目開發(fā)的,我們做的不是這樣規(guī)模的項目。但是我們需要記錄下整個項目的開發(fā)過程,通過這個過程中產出的工件任何一個人可以看出這個項目是如何實現(xiàn)出來的,其目的在于規(guī)避唯有從海量代碼中才能熟悉項目實現(xiàn)這種問題。這里出現(xiàn)了一個概念:工件,其指的是軟件項目開發(fā)過程中任何留下記錄的事物,例如文檔、圖、代碼等。RUP的一個重要思想,在于其整個軟件開發(fā)過程都是可推導的。例如我們通常說的軟件架構,或小一點的模塊結構,都是通過開發(fā)過程中前面階段產出的工件推導得出,而不是憑借程序員的經驗拍腦袋想出來的(經驗不太可靠,并且千差萬別,而推導意味著將每個環(huán)節(jié)變得可靠)。我們借助RUP的這個特性,創(chuàng)建這些工件,用以建立起軟件實現(xiàn)的可靠知識庫。
RUP概覽
以下均摘自<Thinking in UML>中對RUP的描述:
統(tǒng)一過程歸納和集成了軟件開發(fā)活動中的最佳實踐,它定義了軟件開發(fā)過程中最重要的階段和工作(四個階段和九個核心工作流),定義了參與軟件開發(fā)過程的各種角色和他們的職責,還定義了軟件生產過程中產生的工件,并提供了模板。最后,采用演進式軟件生命周期(迭代)將工作、角色和工件串在一起,形成了統(tǒng)一過程。
統(tǒng)一過程是一種追求穩(wěn)定的軟件方法,它追求開發(fā)穩(wěn)定架構,控制變更
統(tǒng)一過程集成了面向對象方法、UML語言、核心工作流、工件模板和過程指導等知識
簡單來說,RUP作為一種軟件項目開發(fā)方法學,它定義了軟件開發(fā)的每一個過程,最重要的是它指導了在每一個過程需要產出什么,這些產出又是怎樣得到。它試圖規(guī)范化整個流程,以規(guī)避需求變更,項目參與者水平不一等帶來的項目不可控等問題,以期一個軟件產品穩(wěn)定地開發(fā)出來。在一個項目開發(fā)過程中,最核心的資源是人,最不可控的亦是人。
RUP過程與實踐
我覺得要快速學習一種知識,需要首先獲得這門知識的總體框架。另一方面,在我們獲得更多信息后,我們需要挖掘出這門知識的核心思想。學習RUP我覺得從這兩方面入手是相對比較快速和有效的手段。
RUP框架
RUP定義了軟件開發(fā)過程的四個階段,以及9個工作流程。一張極為經典的RUP開發(fā)過程框架圖如下:

RUP將整個軟件開發(fā)過程分為四個階段:
- 先啟(Inception)、
- 精化(Elaboration)
- 構建(Construction)
- 產品化(Transition)
每一個階段的工作分為9個流程:
- 業(yè)務建模
- 需求
- 分析設計
- 實施
- 測試
- 部署
- 配置與變更管理
- 項目管理
- 環(huán)境
其中,前6個流程被統(tǒng)稱為”engineering disciplines”,后3個流程被稱為”supporting disciplines”。當然,我們主要關注前6個流程。那么,這些工作流程和開發(fā)階段又有什么關系呢?上圖中其實已經闡明了這些關系。
RUP指導迭代開發(fā)。在軟件開發(fā)的這4個階段中,每一個階段會被分為若干次迭代。而每一次迭代則涵蓋了這9個工作流程。隨著開發(fā)階段向產品化靠近,自然而然地,需求的變更、增加自然會減少,所以從圖中可以看出,開發(fā)過程越到后期,其工作流程中關于需求的工作則越少。同樣,在先啟階段,其需求相關的工作則占據了該階段的主要工作內容。
RUP中的迭代要求在每一次迭代中,都會完整地實施一遍整個工作流程。在軟件實施階段,甚至會在每一個迭代過程完后輸出一個可運行的軟件版本。這個版本可能會被交付給客戶,以期進一步地在功能需求上取得與客戶一致的意見。這倒是同敏捷開發(fā)有點類似。
既然制定了工作流程,那每一個工作流程該如何去實施呢?RUP制定了每個工作流程需要參與的角色,這些角色需要從事的活動,以及這些活動產生的工件。
這句話實際上反映了RUP的一個重要信息,摘自wiki:
RUP is based on a set of building blocks, or content elements, describing what is to be produced, the necessary skills required and the step-by-step explanation describing how specific development goals are to be achieved. The main building blocks, or content elements, are the following:
- Roles (who) – A Role defines a set of related skills, competencies and responsibilities.
- Work Products (what) – A Work Product represents something resulting from a task, including all the documents and models produced while working through the process.
- Tasks (how) – A Task describes a unit of work assigned to a Role that provides a meaningful result.
RUP建模
在我看來,RUP每個工作流程所完成的工作,就是一個建模的過程。所謂建模,簡單來說就是將需要描述的事物通過更系統(tǒng)的形式表達出來,以期獲得對該事物更深入的理解。<Thinking in UML>中定義建模概念為:
建模(modeling),是指通過對客觀事物建立一種抽象的方法用以表征事物并獲得對事物本身的理解,同時把這種理解概念化,將這些邏輯概念組織起來,構成一種對所觀察的對象的內部結構和工作原理的便于理解的表達。
在這里,建模的過程需要使用一些工具。在RUP中建模使用UML來完成。在<Thinking in UML>中講述了UML的核心模型,包括:
- 業(yè)務用例模型
- 概念用例模型
- 系統(tǒng)用例模型
- 領域模型
- 分析模型
- 軟件架構和框架
- 設計模型
- 組件模型
- 實施模型
可能在大家的普遍認識中,UML無非就是幾種圖,并且粗看一眼理解起來也不困難,甚至還能用來畫畫類圖做下代碼結構設計。但UML的作用不僅僅如此。
以上所描述的UML核心模型中,每個模型并不單指的的是一種UML圖。每個模型實際上都會包含幾種UML圖,會包含若干張UML圖。這些模型基本上滲透于RUP的9個工作流程中,只不過不同的工作流程使用的模型比重不一而已。
例如在“分析設計”工作流程中,可能會使用到系統(tǒng)用例模型、分析模型、軟件架構和框架、設計模型等,而業(yè)務用例模型可能在這個流程中根本不會用到;相反,業(yè)務用例模型則可能在“業(yè)務建模”流程中被廣泛使用。
前已述及在RUP的每個工作流程中,RUP定義了該流程需要參與的角色,以及這些角色需要進行的活動,例如這里可以看看“分析設計”流程中的角色和活動集(摘自<Thinking in UML>):

相應的,在該工作流程中需要產出的工件集為(摘自<Thinking in UML>):

既然使用了UML作為建模工具,所以可以簡單地說這些工件主要就是UML圖,當然也會有其他文檔性質的事物,例如網絡協(xié)議結構、數據庫表等UML無法描述的東西則通過普通文字性文檔描述。
RUP最佳實踐
到目前為止我們已經了解到RUP定義了開發(fā)過程(phase),定義了每個過程包含的若干工作流程,還定義了每個工作流程需要哪些角色從事哪些活動來完成哪些工件。除此之外,RUP還提供了6條最佳實踐用以指導軟件開發(fā):
- 迭代開發(fā)
- 管理需求
- 使用基于組件的架構
- 可視建模
- 持續(xù)的質量驗證
- 控制變更
這些實踐在我看來僅僅是一些項目開發(fā)的指導原則,它們滲透到每一個過程,每一個工作流程。在項目過程中實踐這些原則,用以確保項目的成功。例如我們使用UML建模,以達到“可視建模”。我們通過建立需求用例,以“管理需求”。
RUP核心思想
似乎沒有文檔來專門闡述RUP的核心思想,但我覺得掌握其核心思想才是學習的要點所在。要理解一種軟件開發(fā)方法學的核心思想,其實最好是將其與別的方法學做比較。這里先就我的一些感想做闡述。
用例驅動
用例驅動指的是整個軟件項目的推進過程,是依靠“用例”來完成。<Thinking in UML>:
在實際的軟件項目中,一個軟件要實現(xiàn)的功能通過用例來捕獲,接下來的所有分析、設計、實現(xiàn)、測試都由用例來取得,即以實現(xiàn)用例為目標。在統(tǒng)一過程中用例能夠驅動的不僅僅是分析設計。
用例簡單來說就是描述了一個系統(tǒng)功能。但必須注意的是,這僅僅是它定義的一小部分。用例主要分布在“業(yè)務建模”、“需求”、“分析設計”這些工作過程中。在不同的過程中用例的粒度和性質都不一樣。例如對于一個借書系統(tǒng)而言,在業(yè)務建模階段,我們可以獲取出一個“借書”用例,其系統(tǒng)邊界甚至不是系統(tǒng)而可能僅關注這個業(yè)務本身(因為這個階段還沒有考慮到計算機如何實現(xiàn)這個借書業(yè)務);在系統(tǒng)分析階段,我們就可以將“借書”這個用例細化為用戶和計算機軟件系統(tǒng)的交互;進一步地,我們可能會進一步精化這個用例,例如用戶通過網頁終端“借書”。(這里描述了很多建模的細節(jié),可不必深究,本文只給出一個概要性的介紹)
我們說用例驅動軟件開發(fā),但它如何驅動的呢?我在實際的建模過程中,最明顯的感受就是用例驅動了整個建模過程。
- 在需求分析階段,我以系統(tǒng)使用者的角度繪制出了一份用例圖,用于表達使用者對該系統(tǒng)的需求
- 然后我繪制序列圖(活動圖等)來實現(xiàn)這些用例,也就是闡述使用者具體是如何與系統(tǒng)交互的
- 從之前的建模過程中我獲得對系統(tǒng)功能需求方面的認識
- 基于前面的分析我可以繪制出系統(tǒng)用例圖,以明確系統(tǒng)的各個功能需求
- 同樣針對用例繪制用例實現(xiàn)圖
- 用例本身應該包含更多的文檔,因此我編寫用例規(guī)約用以詳細描述各個用例
- 從用例規(guī)約、用例實現(xiàn)中我可以抽離出一些分析類(較設計類更高抽象的類),包含用例場景中涉及到的實體,控制邏輯
- 細化這些分析類,將分析類組織起來形成系統(tǒng),我會用界面類去銜接各個控制類
- 將得到的分析類按模塊來劃分,從而可以得到一個初步的系統(tǒng)架構
- 初步考慮系統(tǒng)實現(xiàn),我甚至會得到一個初步是的系統(tǒng)部署圖
- 回過頭不斷審視系統(tǒng)用例,以確認我是否實現(xiàn)了所有用例,這可以保證我的分析實現(xiàn)了所有需求,我不用枚舉所有系統(tǒng)特性是否被我考慮周全,我僅需在已有用例圖中核實
- 基于模塊實現(xiàn)各個用例,或者基于分析類來實現(xiàn)系統(tǒng)用例
- 通過重新繪制以及核實用例,可以進一步精化分析類,分析類在很大程度上會一一對應到設計類,而設計類則對應到實際的代碼
- 可以進入設計階段,設計階段會考慮到系統(tǒng)的實現(xiàn)細節(jié),例如使用的語言,使用的框架等
進入設計階段后,雖然可以進一步建模,得到會直接映射到代碼的類圖、序列圖等,但這樣的圖在面臨需求變更時,基本上會面臨修改,這意味著維護這些文檔需要耗費精力。所以,<Thinking in UML>中主張將精力放在維護分析類模型中,而通過其他約定實現(xiàn)從分析類到實際代碼的轉換。我覺得這個也在理。
規(guī)范化整個過程
我個人覺得RUP的一大特點在于規(guī)范化了整個軟件開發(fā)過程,每一個步驟需要哪些角色參與,該干什么,怎么去干都有指導。加之這些活動的”可推導性“,這意味著不論參與角色屬于什么水平,都可以穩(wěn)固地推進項目進程。
此外,這種規(guī)范化也會給項目留下詳細的演化過程。你可以明確地看到整個軟件是如何演化出最終的產品代碼,可以深入地理解項目代碼中的設計。
總結
我只是一個RUP新手,即便如此,我依然不覺得RUP是軟件開發(fā)的萬能藥。我相信任何軟件開發(fā)方法都是有局限性的。我們在實際使用的時候也只是吸取其精華。不同的開發(fā)方法其適用范圍也是不一樣的。正如有人將RUP和XP做比較時說,如果你使用RUP去開一個雜貨鋪,在沒開張之前你就已經破產了;同樣如果你用XP去做飛機,飛機毀了十來次也許才能做出來(from <Thinking in UML> again)。
參考文檔