簡介 迭代開發是OOA/D成為最佳實踐的核心,也是本書所介紹的OOA/D的核心。 敏捷實踐(如敏捷建模)是有效地應用UML的關鍵。UP是相對流行的、示范性的迭代方法。本章將對這些主題進行介紹。
相對于順序或“瀑布”(waterfall)生命周期,迭代和進化式開發(interative and evolutionary development)對部分系統及早地引入了編程和測試,并重復這一循環。這種方式通常會在還沒有詳細定義所有需求的情況下假設開發開始,同時使用反饋來明確和改進演化中的規格說明。
在迭代開發中,我們依賴于短時快速的開發步驟、反饋和改寫來不斷明確需求和設計。相比之下,瀑布模型提倡在編程之前就預先完成需求和設計步驟。一直以來,成功/失敗的研究表明,瀑布模型和軟件項目高失敗率具有極大關系,對它的推廣源于信念和風聞,而不是具有統計意義的證據。研究證實,迭代方法與較高的成功率、生產率和低缺陷率具有關系。
什么事UP? 其他方法能否對其進行補充 軟件開發工程描述了構造、部署以及維護軟件的方式。 統一過程已經成為一種流行的構造面向對象系統的迭代軟件開發過程。特別是,Rational統一過程(Rational Unified Process ,RUP)是對統一過程的詳細精化,并且已經被廣泛采納。
UP是十分靈活和開放的,并且鼓勵引進其他迭代方法中的有用的實踐,諸如極限編程(Extreme Programming,XP)、Scrum等等。 例如,在UP項目中可以引入XP的測試驅動開發(test-driven development)、重構(refactoring)和持續集成(continuous integration)等實踐。同樣,也可以引入Scrum的公共項目室(“作戰室”)和Scrum日常會議等實踐。
概括而言,本章介紹UP源于下述三個理由:
1、UP是迭代過程。迭代開發對本書介紹OOA/D的方式,以及OOA/D的最佳實踐具有影響。
2、UP實踐提供了如何實施OOA/D的示范結構。這也形成了本書的結構。
3、UP具有靈活性,可以應用于輕量級和敏捷方法,這些方法包括其他敏捷方法(諸如XP或Scrum)的實現,稍后將對此作更多介紹。
什么是迭代和進化式開發 迭代開發(interative development)是UP和大多數其他現代方法中的關鍵實踐。在這種生命周期方法中,開發被組織成一系列固定的短期(如三個星期)小項目,稱為迭代(iterative),每次迭代都產生經過測試、集成并可執行的局部系統。每次迭代都具有各自的需求分析、設計、實現和測試活動。
迭代生命周期基于對經過多次迭代的系統進行持續擴展和精化,并以循環反饋和調整為核心驅動力,使之最終成為適當的系統。隨著時間和一次又一次迭代的遞進,系統增量式地發展完善,因此這一方法也被稱為迭代和增量式開發(interative and incremental development)(參見圖2-1)。因為反饋和調整使規格說明和設計不斷進化,所以這種方法也稱為迭代和進化式開發(interative and evolutionary development)。
每次迭代都產生可執行的但不完整的系統,它不是已經準備好可以交付的產品。直到多次迭代之后,系統才能夠合格的用于產品部署。
迭代的輸出不是實驗性的或將丟棄的原型,迭代開發也不是構造原型。與之相反,其輸出是最終系統的產品子集。
如何在迭代項目中處理變更
每次迭代選擇一小組需求,并快速設計、實現和測試。在早期迭代中,對需求和設計的選擇對于最終期望來說可能并不準確。但是,在最終確定所有需求或經過深思熟慮而定義完整設計之前,快速地實施一小步的方式可以得到快速反饋--來自用戶、開發人員和測試的反饋。
這種反饋具有極高的價值。與“推測”完整、正確的需求或設計相反,團隊可以從實際構造和測試的反饋中,挖掘出至關重要和實際的觀點,并修改和調整對需求或設計的理解。 早期頻繁地在“不錯。。。但是”中循環,正是改進軟件和發現什么對涉眾有真正價值的實用方式。然而這并非對開發者不斷變換方向的無序和反應式開發的認可,作為一條中間路線是可行的。
除了明確需求之外,負載測試將驗證局部設計和實現是否正確,或者是否需要在下次迭代中改變核心架構。最好及早解決和驗證具有風險的、關鍵的設計決策,而迭代開發提供了完成這項工作的機制。
因此,工作是通過一系列有序的構造--反饋--調整循環向前進展的。早期迭代中系統偏離“正確軌跡”的程度會大于后繼迭代。隨著時間的發展,系統將沿著這一軌跡收斂。如圖2-2
迭代開發的優點
迭代開發的優點包括:
1、減少項目失敗可能性,提高生產率,降低缺陷率。對迭代和進化式的研究表明了這一點。
2、在早期(而不是晚期)緩解高風險(技術、需求、目標、可用性等等)
3、早期可見的進展
4、早期反饋、用戶參與和調整,會產生更接近涉眾真實需求的精化系統。
5、可控復雜性:團隊不會被“分析癱瘓”或長期且復雜的步驟所淹沒
6、一次迭代中的經驗可以被系統地用于改進開發過程本身,并如此反復進行下去。
一次迭代的持續時間和時間定量
大部分迭代方法建議迭代時間在2~6周之間。小步驟、快速反饋和調整時迭代開發的主要思想,迭代時間過長會破壞迭代開發的核心動機并增加項目風險。 迭代的一個關鍵思想是時間定量(timeboxed),或時長固定。
什么是瀑布生命周期 在瀑布生命周期過程中,試圖在編程之前(詳細定義所有或大部分需求)。而且在通常與編程之前創建出完整的設計。同樣,會試圖在開始前定義“可靠的”計劃或時間表,但常常事與愿違。
反饋和改寫的必要性
在復雜、變更系統中(如大多數軟件項目),反饋和調整是成功的關鍵要素。
1、來自早期開發中的反饋,有助于程序設計人員理解規格說明,客戶演示也有助于精化需求。
2、來自測試中的反饋,有助于開發者精化設計或模型。
3、來自團隊處理早期特性過程中的反饋,有助于精化時間表和估計
4、來自客戶和市場的反饋,有助于重新定義下一次迭代實現特性的優先級。
+ -
如何進行進化和迭代式分析和設計 這里的介紹可能會給人留下這樣的印象,即編程前的分析和設計毫無價值,但這是與瀑布思維同樣偏激的誤解。迭代和進化式分析設計師中庸之道。這里有個簡短的例子,用以說明在運轉良好的UP項目中,迭代方法是如何被運用的。這里假設在項目交付前,最終將有20次迭代。
-
在第一次迭代之前,召開第一個時間定量的需求工作會議,例如確切的定義為兩天時間。業務和開發人員(包括首席架構師)需要出席。
1> 在第一天上午,進行高階需求分析,例如僅僅確定用例和特性的名稱,以及關鍵的非功能性需求。這種分析不可能是完美的。
2> 通過咨詢首席架構師和業務人員,從高階列表中選擇10%列表項(例如,30個用例中的10%),這些項目要具備以下三種性質:A、具有重要的架構意義(如果要實現,我們必須設計、構造和測試的核心架構) B、具有高業務價值(業務真正關心的特性) C、具有高風險(例如“能夠處理500個并發交易”等)。所選的三個用例可能被標識為:UC2、UC11和UC14。
3>在剩下的一天半內,對這三個用例的功能和非功能性需求進行詳細的分析。完成這一過程后,對10%進行了深入分析,90%進行了高階分析。
在第一次迭代之前,召開迭代計劃會議,選擇UC2、UC11和UC14的子集,在特定時間內(例如,四周的時間定量迭代)進行設計、構造和測試。要注意的是,因為其中包含大量工作,所以并不是在第1次迭代中就要構造出全部三個用例。在選擇了特定子集目標后,在開發團隊的幫助下,將其分解為一系列更為詳細的迭代任務。
在三到四周內完成第1次迭代(選擇時間定量,并嚴格遵守時間)。
1> 在開始的兩天內,開發者和其他成員分組進行建模和設計工作,在首席架構師的帶領和指導 下,于“公共作戰室”的眾多白板上,畫出UML的草圖(及其他的模型)。
2> 然后,開發者摘掉其"建模帽子"并帶上"編程帽子",開始編程、測試和集成工作并且剩余的時間均用于完成這項工作。開發者將建模草圖作為其靈感的起點,但要清楚這些模型只是局部的,并且通常是含糊的。
3> 進行大量的測試,包括單元測試、驗收測試、負載測試和可用性測試等。
4> 在結束前的一周,檢查是否能夠完成初始的迭代目標;如果不能,則縮小迭代的范圍,將次要目標置回任務列表中。
5> 在最后一周的星期二,凍結代碼;必須檢入、集成和測試所有代碼,以建立迭代的基線。
6> 在 星期三的上午,向外部涉眾演示此局部系統,展示早期可視進展,同時要求反饋。
在第一次迭代即將結束時(如最后一周的星期三和星期四),召開第二次需求工作會,對上一次會議的所有材料進行復查和精化。然后選擇具有重要架構意義和高業務價值的另外10%到15%的用例,用一到兩天對其進行詳細分析。這項工作完成后,會詳細記錄下大概25%的用例和非功能性需求。當然,這也不是完美的。
于周五上午,舉行下一次的迭代計劃會議。
以相同步驟進行第二次迭代
反復進行四次迭代和五次需求工作會,這樣在第四次迭代結束時,可能已經詳細記錄了約80%~90%的需求但只實現了系統的10% (注意,這些大量、詳細的需求集是基于反饋和進化的,因此其質量遠高于純粹依靠推測而得出的瀑布式規格說明)
我們大概推進了整個項目過程的20%。在UP的術語里,這是細化階段(elaboration phase)的結束。此時,可以估計這些精化的、高質量的需求所需工作量和時間。因為具有依據現實得出的調查、反饋結論并進行了早期編程和測試,因此估計能夠做什么和需要多長時間的結果會更為可靠。
此后,一般不需要再召開需求工作會;需求已經穩定了(盡管需求永遠不會被凍結)。接下來是一系列為期三周的迭代,在最后一個周五召開的迭代計劃會議上選擇適宜的下一步工作,每次迭代都要反復詢問:“就我們現在所知,下一個三周應該完成的、最關鍵的技術和業務特性是什么?”
PPT2-5 中描述了經過20次迭代的項目。
利用這種方式、經過早期探索式開發的幾次迭代之后,團隊將能夠更準確地回答“什么、多少、何時”。
什么是風險驅動和客戶驅動的迭代計劃 UP(及大多數新方法)提倡風險驅動(risk-driven)與客戶驅動(client-driven)相結合的迭代計劃。這意味著早期的迭代目標要能夠識別和降低最高風險,并且能構造客戶最關心的可視化特性。
風險驅動迭代開發更為明確地包含了以架構為中心(architecture-centric)迭代開發的實踐,意味著早期迭代要致力于核心架構的構造、測試和穩定。為什么?因為沒有穩固的架構就會帶來高風險。
什么是敏捷方法及其觀點 敏捷開發(agile development)方法通常應用時間定量的迭代和進化式開發、使用自適應計劃、提倡增量交付并包含其他提倡敏捷性(快速和靈活的響應變更)的價值和實踐。除此之外,他們還提倡反映簡易、輕量、溝通、自組織團隊等更多敏捷性的實踐和原則。
Scrum敏捷方法中的實踐范例包括公共項目工作室和自組織團隊,這些實踐通過每日例行會議來協調工作,在例會上要求每位成員回答四個特定的問題。 極限編程(XP)方法中的實踐范例包括結對編程和測試驅動開發(test-driven development)。
包括UP在內的任何迭代方法都可以施加以敏捷精神。
什么是敏捷建模 有經驗的分析員和建模者了解以下這條建模的秘訣: 建模(構建UML草圖)的目的主要是為了理解,而非文檔。 也就是說,建模的真正行為能夠并且是應該能夠對理解問題或解決方案空間提供更好的方式。
在"Agile Modeling" 一書中,將這種觀點及與之一致的敏捷方法稱為敏捷建模(agile modeling)。 這其中包含了以下許多實踐和價值:
1、采用敏捷方法并不意味著不進行任何建模,這是個錯誤理解。Feature-Driven Development、DSDM和Scrum等許多敏捷方法、一般都包含重要的建模期。正如Ambler(XP 方法和敏捷建模的專家)所言,即便是XP(可能是最少強調建模的最為知名的敏捷方法)的奠基人也認可敏捷建模,并且多年來有大量建模者都在實踐中采用了敏捷建模。
2、建模和模型的目的主要用于理解和溝通,而不是構建文檔。
3、不要對所有或大多數軟件設計建模或應用UML。可以將簡單的設計問題推延到編程階段,在編程和測試過程中解決這些問題。只需對設計空間中不常見、困難和棘手的一小部分問題建模和應用UML
4、盡可能使用最簡單的工具。建議使用支持快速輸入和改變的“低能耗”創造力增強型的簡易工具。同時,選擇支持大可視空間的工具。例如,最好在白板上草圖UML,使用數碼相機捕獲圖形。(這里 并不是說UML CASE工具或字處理軟件不可取或毫無價值,但是對于創造性工作來說,在白板上畫草圖更為流暢并便于修改。關鍵的規則是簡單和敏捷,而不論使用何種技術)
5、不要單獨建模,而是結對在白板上建模,同時要記住建模的目的是發現、理解和共享大家的理解。小組成員要輪流畫草圖,以使每個人都參與其中。
6、并行的創建模型。例如,在一塊白板上勾勒UML動態視圖的交互圖,同時在另一白板上勾畫出補充性的UML靜態視圖的類圖。同時開發這兩種模型(視圖),并不斷交替。
7、在白板上用筆畫草圖時,應使用“足夠好”的簡單表示法。UML細節是否精準并不重要,關鍵是建模者能夠互相理解,堅持使用簡單、常用的UML元素。
8、要知道所有模型都可能是不準確的,最終代碼或設計會與模型有差異,甚至具有極大的差異。只有測試過的代碼才能證實真正的設計;先前繪制的模型圖都是不完整的,最好只是將其視為一次探索。
9、開發者應該為自己進行OO設計建模,而不是創建模型圖后交給其他編程者去實現--這是非敏捷的面向瀑布的方法。
本書中的敏捷建模:為什么使用UML草圖的快照 因為這些圖是為了提高可讀性而使用工具精心繪制的。為了讓大家感受真實情況,本書有時會使用在白板繪制的UML草圖的數碼快照。這樣雖然易讀性差一些,但是可以提醒讀者敏捷建模是很有用的,并且這種方式是案例研究所使用的實際工作方式。
什么是敏捷UP UP的創始人并沒有為其賦予重量級或非敏捷的含義,盡管其龐大的可選活動集和制品集會給人留下這種印象。實際上,UP可以采納和應用可適應性和輕量級的精神--敏捷UP。以下是應用的一些示例:
1、推薦使用UP活動和制品的簡集。雖然某些項目得益于使用較多的UML活動和制品,但一般來說應該保持簡潔。要記住,所有UP制品都是可選的,除非它們能增加價值,否則避免創建這些制品。應該致力于早期的編程,而非構建文檔。
2、UP是迭代和不斷進化的,所以在實現前的需求和設計師不完整的。它們是在一系列迭代中,基于反饋而產生的。
3、以敏捷建模實踐應用UML
4、對于整個項目不應有詳細的計劃。應該制定估計結束日期和主要里程碑的高階計劃(稱為階段計劃),但是不要對這些里程碑詳細定義細粒度的步驟。只能預先對一個迭代制定更為詳細的計劃(稱為迭代計劃)。詳細計劃是由一次次迭代的調整而完成的。
UP的其他關鍵實踐 UP所倡導的核心思想是:短時間定量迭代、進化和可適應性開發。其他一些UP的最佳實踐和關鍵概念包括:
1、在早期迭代中解決高風險和高價值的問題
2、不斷地讓用戶參與評估、反饋和需求
3、在早期迭代中建立內聚的核心架構
4、不斷的驗證質量;提早、經常和實際地測試
5、在適當的地方使用用例
6、進行一些可視化建模(使用UML)
7、認真管理需求
8、實時變更請求和配置管理
什么是UP的階段 UP項目將其工作和迭代組織為四個主要階段:
1、初始(Inception):大體上的構想、業務案例、范圍和模糊評估
2、細化(Elaboration):已精化的構想、核心架構的迭代實現、高風險的解決、確定大多數需求和范圍以及進行更為實際的評估
3、構造(Construction):對遺留下來的風險較低和比較簡單的元素進行迭代實現,準備部署
4、移交(Transition):進行beta測試和部署
圖2-6說明了UP中常用的面向進度表的術語。注意,一個開發周期(以系統發布為產品作為結束標志)由多個迭代組成
什么是UP科目 UP描述了科目(discipline)中的工作活動,例如編寫用例。科目是在一個主題域中的一組活動(及相關制品),例如需求分析中的活動。在UP中,制品(artifact)是對所有工作產品的統稱,如代碼、Web圖形、數據庫模式、文本文檔、圖、模型等。
UP中有幾個科目,本書中只關注以下三個科目中的制品:
1、業務建模: 領域模型制品,使應用領域中的重要概念的可視化。
2、需求:用以捕獲功能需求和非功能需求的用例模型及其補充性的規格說明制品。
3、設計:設計模型制品,用于對軟件對象進行設計。
圖2-7列出了更多的UP科目。 在圖中,實現表示編程和構建系統,而不是部署。環境科目是指建立工具并為項目定制過程,也就是說,設置工具和過程環境。
科目和階段之間的關系 如圖2-7所示,一次迭代的工作會遍歷大部分或全部科目。然而,跨越這些科目的相對工作量會隨著時間發生變化。自然而然,早期迭代傾向于更多的需求和設計,后期迭代則較少進行這方面的工作,因為通過反饋和改寫過程,需求和核心已經趨向于穩定。
就UP階段(初始、細化等)的這一主題,圖2-8闡述了對應于各階段的相對工作量的變化。請注意,這只是建設性意見,而非強制。
UP階段和科目對本書結構的影響 案例研究強調初始和細化階段。其重點是業務建模、需求和設計科目中的一些制品,因為這些都是需求分析、OOA/D、模式和UML的主要應用之處。
下面的列表和圖2-9描述了本書關于UP階段的組織。
1、初始階段對應的章介紹需求分析的基本內容
2、迭代1介紹OOA/D基礎和如何為對象分配職責
3、迭代2的重點是對象設計,特別介紹一些經常使用的“設計模式”
4、迭代3介紹各種主題,例如架構分析和框架設計。
如何定制過程和UP開發案例
UP中有可選制品或實踐嗎 當然! 幾乎所有的制品和實踐都是可選的。也就是說,某些UP實踐和原則是一成不變的,例如迭代和風險驅動開發以及質量的持續驗證。 然而,UP的一個關鍵內涵是,所有活動和制品(模型、圖、文檔。。。)都是可選的--或許除了代碼!
UP中描述的一組可能的制品可以看作藥房里的一組藥劑。就像不會有人不加選擇地隨便吃藥,而是要對癥下藥一樣,對于UP項目,開發團隊應該選擇一組能夠解決其特定問題和需要的制品。一般來說,要關注一組具有較高實踐價值的制品。
定義:什么是開發案例 為項目選擇實踐和UP制品可以編寫為簡短文檔,這稱為開發案例(環境科目中的制品)(PPT01)可以作為本書所探討的"NextGen項目"案例研究中的開發案例
判斷你是否理解迭代開發或UP 若出現以下跡象,表明你并沒有理解以敏捷精神采用迭代開發和UP的真正含義。
1、在開始設計或實現之前試圖定義大多數需求。同樣,在開始實現之前試圖定義大多數設計;試圖在迭代編程和測試之前定義和提交完整的架構
2、在編程之前花費數日或數周進行UML建模,或者認為在繪制UML圖和進行設計時要準確完整地定義及其詳細的設計和模型。并且,認為編程只是簡單機械地將其轉換為代碼的過程
3、認為初始階段=需求階段,細化階段=設計階段,構造階段=實現階段(也就是說將瀑布模型疊加于UP之上)
4、認為細化的目的是完整仔細地定義模型,以能夠在構造階段將其轉換為代碼
5、堅信合適的迭代時間長度為三個月之久,而不是三周
6、認為采用UP就意味著要完成大量可能的活動和創建大量的文檔,并且認為UP是需要遵循大量步驟的、正規和繁瑣的過程
7、試圖對項目從開始到結束制定詳細計劃;試圖預測所有迭代,以及每個迭代中可能發生的事情。