VOOZH about

URL: https://read01.com/7ReOn3.html

⇱ 敏捷軟體開發:極限編程概述 - 壹讀


Saturday, Apr 11, 2026

敏捷軟體開發:極限編程概述

2015/09/10 來源:光環國際
👁 Image
...

1.1極限編程實踐

1.1.1完整團隊

我們希望客戶、管理者和開發人員緊密地工作在一起,以便於彼此知曉對方所面臨的問題,並共同去解決這些問題。誰是客戶?XP團隊中的客戶是指定義產品的特性並排列這些特性優先級的人或者團體。有時,客戶是和開發人員同屬一家公司的一組業務分析師、質量保證專家和/或者市場專家。有時,客戶是用戶團體委派的用戶代表。有時,客戶事實上是支付開發費用的人。但是在XP項目中,無論誰是客戶,他們都是能夠和團隊一起工作的團隊成員。

最好的情況是客戶和開發人員在同一個房間中工作,次一點的情況是客戶和開發人員之間的工作距離在100m以內。距離越大,客戶就越難成為真正的團隊成員。如果客戶工作在另外一幢建築或另外一個州,那麼他將會很難融合到團隊中來。

如果確實無法和客戶工作在一起,該怎麼辦呢?我的建議是去尋找能夠在一起工作、願意並能夠代替真正客戶的人。

1.1.2用戶故事

為了進行項目計劃,必須要了解需求,但是卻無需了解得太多。對於做計劃而言,了解需求只需要到能夠估算它的程度就足夠了。你可能認為,為了對需求進行估算,就必須要了解該需求的所有細節。其實並非如此。你必須知道存在很多的細節,也必須知道細節的大致分類,但是你不必知道特定的細節。

需求的具體細節很可能會隨時間而改變,一旦客戶開始看到集成到一起的系統,就更會如此。看到新系統的問世是關注需求的最好時刻。因此,不要去捕獲某個在很長一段時間之後才會實現的需求的特定細節,否則很可能會導致無用功以及對需求不成熟的關注。

在XP中,我們和客戶反覆討論,以獲取對於需求細節的理解,但是不去記錄那些細節。我們更願意客戶在索引卡片上寫下一些共識的言語,這些隻言片語可以提醒我們記起這次交談。基本上在客戶進行書寫的同一時刻,開發人員在該卡片上寫下對應於卡片上需求的估算。估算是基於在和客戶進行交談期間所得到的對於細節的理解進行的。

用戶故事(user story)就是正在進行的關於需求的談話的助記符。它是一個計劃工具,客戶可以使用它並根據需求的優先級和估算代價來安排實現該需求的時間。

1.1.3短交付周期

XP項目每兩周交付一次可以工作的軟體。每兩周的疊代都實現了利益相關者的一些需求。在每次疊代結束時,會給利益相關者演示疊代生成的系統,以得到他們的反饋。

疊代計劃

每次疊代通常耗時兩周。疊代是一次較小的交付,可能會被加入到產品中,也可能不會。疊代計劃由一組用戶故事組成,這些用戶故事是客戶根據開發人員確定的預算選出來的。

開發人員通過度量在以前的疊代中所完成的工作量來為本次疊代設定預算。只要估算成本的總量不超過預算,客戶就可以為本次疊代選擇任意數量的用戶故事。

一旦疊代開始,客戶就同意不再修改當次疊代中用戶故事的定義和優先級別。疊代期間,開發人員可以自由地將用戶故事分解成任務(task),並依據最具技術和商業意義的順序來開發這些任務。

發布計劃

XP團隊通常會創建一個發布計劃來規劃出隨後大約6次疊代的內容。這就是所謂的發布計劃。一次發布通常需要3個月的工作。它表示了一次較大的交付,通常此次交付會被加入到產品中。發布計劃是由客戶根據開發人員給出的預算所選擇的、排好優先級別的一組用戶故事組成。

開發人員通過度量在以前的發布中所完成的工作量來為本次發布設定預算。只要估算成本的總量不超過預算,客戶就可以為本次發布選擇任意數目的用戶故事。客戶同樣可以決定在本次發布中用戶故事的實現順序。如果開發團隊強烈要求的話,客戶可以通過指明哪些用戶故事應該在哪次疊代中完成的方式,制訂出發布中最初幾次疊代的內容。

發布計劃不是一成不變的。客戶可以隨時改變發布的內容。他可以取消用戶故事,編寫新的用戶故事,或者改變用戶故事的優先級別。但是,客戶應該儘量不去更改一次疊代。

1.1.4驗收測試

可以以客戶指定的驗收測試的形式來記錄有關用戶故事的細節。用戶故事的驗收測試是在就要實現該用戶故事之前,或者在實現該用戶故事的同時才開始編寫的。驗收測試使用腳本語言編寫,這樣它們可以自動、反覆地運行。這些測試共同來驗證系統是否按照客戶指定的行為運轉。

驗收測試是由業務分析師、質量保證專家以及測試人員在疊代期間編寫的。編寫驗收測試使用的語言對於程式設計師、客戶以及業務人員來說都很容易閱讀和理解。程式設計師就是從這些測試中了解他們正在實現的故事的真實工作細節。這些測試成為真正的項目需求文檔。驗收測試描述了每個特性的所有細節,並用作驗證這些特性是否被正確完成的決定性依據。

一旦通過一項驗收測試,就將該測試加入到已經通過的驗收測試集合中,並決不允許該測試再次失敗。這個不斷增長的驗收測試集合每天會多次運行,每當系統被創建時,都要運行這個驗收測試集。如果一項驗收測試失敗了,那麼系統創建就宣告失敗。因而,一項需求一旦被實現,就再不會遭到破壞。系統從一種工作狀態遷移到另一種工作狀態,期間,系統的不能工作狀態時間決不允許超過幾個小時。

1.1.5結對編程

代碼都是由結對的程式設計師使用同一台工作站共同完成的。結對人員中,一個控制鍵盤並輸入代碼。另一個觀察著輸入的代碼,尋找著代碼中的錯誤和可以改進的地方。兩個人認真地進行著交互。他們都全身心地投入到軟體的編寫中。

兩人頻繁互換角色。控制鍵盤的可能累了或者遇到了困難,他的同伴會取得鍵盤的控制權。在一個小時內,鍵盤可能在他們之間來回傳遞好幾次。最終生成的代碼是由他們兩人共同設計、共同編寫的,兩人功勞均等。

結對的關係要經常變換。每天至少要改變一次,這樣每個程式設計師在一天中可以在兩個不同的結對中工作。在一次疊代期間,每個團隊成員應該和所有其他的團隊成員在一起工作過,並且他們應該參與了本次疊代中所涉及的每項工作。

結對編程會極大地促進知識在團隊中的傳播。仍然會需要一些專業知識,那些需要一定專業知識的任務通常需要合適的專家去完成,但是那些專家幾乎將會和團隊中的所有其他人結對。這將加快專業知識在團隊中的傳播。這樣,在緊要關頭,其他團隊成員就能夠代替所需要的專家。Williams和Nosek的研究表明,結對非但不會降低編程人員的效率,反而會大大減少缺陷率。

1.1.6測試驅動開發

第4章會詳細地討論這個主題。在此,我們僅進行大致的介紹。

編寫所有產品代碼的目的都是為了使失敗的單元測試能夠通過。首先編寫一個單元測試,由於它要測試的功能還不存在,所以它會運行失敗。然後,編寫代碼使測試通過。

編寫測試用例和代碼之間的更迭速度是很快的,基本上在幾分鐘左右。測試用例和代碼共同演化,其中測試用例循序漸進地對代碼的編寫進行指導(參見第6章中的例子)。

作為結果,一個非常完整的測試用例集就和代碼一起發展起來。程式設計師可以使用這些測試來檢查程序是否正確地工作。如果結對的程式設計師對代碼進行了小的更改,那麼他們可以運行測試,以確保更改沒有對程序造成任何的破壞。這會非常有利於重構(在本章後面介紹)。

當為了使測試用例通過而編寫代碼時,那麼所編寫的代碼天生就是可測試的。更重要的是,這樣做會強烈地激發你去解除各個模塊間的耦合,以便能夠獨立地對它們進行測試。因而,以這種方式編寫的代碼的設計往往具有更弱的耦合。面向對象設計的原則在進行這種解耦方面具有巨大的幫助作用(參見本書第二部分)。

1.1.7集體所有

每一對編程者都具有簽出(check out)任何模塊並對它進行改進的權力。每個程式設計師都不會對任何一個特定的模塊或技術單獨負責。每個人都參與GUI方面的工作,每個人都參與中間件方面的工作,每個人都參與資料庫方面的工作。任何人都不會比其他人在一個模塊或者技術上具有更多的權威。

這並不意味著XP不需要專業知識。如果你的專業領域是有關GUI的,那麼你最有可能去從事GUI方面的任務,但是你也將會被邀請去和別人結對從事有關中間件和資料庫方面的任務。如果你決定去學習另一門專業知識,那麼你可以承擔相關的任務,並和能夠傳授你這方面知識的專家一起工作。你不會被限制在自己的專業領域。

1.1.8持續集成

程式設計師每天會多次簽入(check in)他們的代碼並進行集成。規則很簡單:第一個簽入的只要完成簽入就可以了,所有後面簽入的人負責代碼的合併工作。

XP團隊使用非阻塞的原始碼控制工具。這就意味著程式設計師可以在任何時候簽出任何模塊,而不管是否有其他人已經簽出了這個模塊。當程式設計師完成了對於模塊的修改並把該模塊簽入時,他必須把他所做的改動和在他前面簽入該模塊的程式設計師所作的任何改動進行合併。為了避免合併的時間過長,團隊的成員會非常頻繁地檢查他們的模塊。

結對人員會在一項任務上工作一到兩個小時。他們創建測試用例和產品代碼。在某個適當的間歇點,也許遠在這項任務完成之前,他們決定把代碼簽入回去。他們首先確保所有的測試都能夠通過,然後把新的代碼集成進當前的代碼庫中。如果需要,他們會對代碼進行合併。如果有必要,他們會和在簽入上有衝突的其他程式設計師協商。一旦集成進了他們的更改,他們就構建新的系統。他們運行系統中的每一個測試,包括當前所有有效的驗收測試。如果他們破壞了原先可以工作的部分,他們會進行修正。一旦所有的測試都通過了,他們就算完成了此次簽入工作。

因而,XP團隊每天會進行多次系統構建。他們會從頭開始創建整個系統。如果系統的最終結果是一張CD,他們就刻錄該CD。如果系統的最終結果是一個可以訪問的Web站點,他們就安裝該Web站點,或許會把它安裝在一個測試伺服器上。

1.1.9可持續的開發速度

軟體項目不是全速短跑,它是馬拉松長跑。那些一躍過起跑線就開始盡力狂奔的團隊將會在遠離終點前就筋疲力盡。為了快速地完成開發,團隊必須要以一種可持續的速度前進。團隊必須保持旺盛的精力和敏銳的警覺。團隊必須要有意識地保持穩定、適中的速度。

XP的規則不允許團隊加班工作。在版本發布前的一個星期是該規則的唯一例外。如果發布目標就在眼前並且能夠一蹴而就,則允許加班。

1.1.10開放的工作空間

團隊在一個開放的房間中一起工作。房間中有一些桌子。每張桌子上擺放了兩到三台工作站。每台工作站前有兩把椅子。牆壁上掛滿了狀態圖表、任務明細表、UML圖,等等。

房間裡充滿了交談的嗡嗡聲,結對編程的兩人坐在互相能夠聽得到的距離內,每個人都可以得知另一人是否遇到了麻煩,每個人都了解對方的工作狀態,程式設計師們都處在適合於激烈地進行討論的位置上。

可能有人認為這種環境會分散人的注意力。很容易會讓人擔心由於持續的噪音和干擾而一事無成。事實上並非如此。而且,密西根大學的一項研究表明,在"充滿積極討論的屋子"(war room)里工作,生產率非但不會降低,反而會成倍地提高。

1.1.11計劃遊戲

計劃遊戲(planning game)的本質是劃分業務和開發之間的職責。業務人員(也就是客戶)決定特性的重要性,開發人員決定實現一個特性所花費的代價。

在每次發布和疊代的開始,開發人員向客戶提供一個預算。客戶選擇那些所需的代價合計起來小於等於該預算的用戶故事。開發者所提供的預算是基於他們在最近一次疊代或者發布中所完成的工作量進行的。

依據這些簡單的規則,採用短周期疊代和頻繁的發布,很快客戶和開發人員就會適應項目的開發節奏。客戶會了解開發人員的開發速度。基於這種了解,客戶能夠確定項目會持續多長時間,以及會花費多少成本。

1.1.12簡單設計

XP團隊使他們的設計儘可能的簡單、有表達力。此外,他們僅僅關注於計劃在本次疊代中要完成的用戶故事,而不會考慮那些未來的用戶故事。團隊更願意在一次次的疊代中不斷地變遷系統的設計,使之對正在實現的用戶故事而言始終保持在最優狀態。

這意味著XP團隊的工作可能不會從基礎設施開始。他們並不先去選擇資料庫或者中間件,而是先以最簡單的可能方式實現第一批用戶故事。只有當出現一個用戶故事迫切需要基礎設施時,他們才會引入該基礎設施。

下面3條XP指導原則(mantra)可以對開發人員進行指導。

(1)考慮能夠工作的最簡單的事情。XP團隊總是儘可能尋找能實現當前用戶故事的最簡單的設計。在實現當前的用戶故事時,如果能夠使用平面文件,就不去使用資料庫;如果能夠使用簡單的socket連接,就不去使用ORB或者Web Service;如果能夠不使用多線程,就別去用它。我們儘量考慮用最簡單的方法來實現當前的用戶故事。然後,選擇一種我們能夠實際得到的和該簡單性最接近的解決方案。

(2)你不需要它。是的,但是我們知道總有一天會需要資料庫,會需要ORB,也總有一天得去支持多用戶。所以,我們現在就需要為那些東西做好準備,不是嗎?

如果在確實需要基礎設施前拒絕引入它,那麼會發生什麼呢?XP團隊會對此進行認真的考慮。他們開始時假設將不需要那些基礎設施。只有在有證據,或者至少有十分明顯的跡像表明現在引入這些基礎設施比繼續等待更加合算時,團隊才會引入這些基礎設施。

(3)一次,並且只有一次。極限編程者不能容忍重複的代碼。無論在哪裡發現重複的代碼,他們都會消除這些重複。

導致代碼重複的因素有許多。最明顯的是通過滑鼠選中一段代碼,然後四處進行粘貼。當發現那些重複的代碼時,我們會通過創建一個函數或基類的方法來消除它們。有時兩個或多個算法非常相似,但是它們之間又存在有微妙的差別,我們會把它們變成函數,或者使用TEMPLATE METHOD模式(請參見第22章)。無論重複代碼源於何處,一旦發現,就必須被消除。

消除重複最好的方法就是抽象。畢竟,如果兩種事物相似的話,必定存在某種抽象能夠統一它們。這樣,消除重複的行為會迫使團隊提煉出許多的抽象,並進一步減少代碼間的耦合。

1.1.13重構

代碼往往會腐化。隨著我們添加一個又一個的特性,處理一個又一個的錯誤,代碼的結構會逐漸退化。如果對此置之不理的話,這種退化最終會導致糾結不清、難於維護的混亂代碼。

XP團隊通過經常性的代碼重構來扭轉這種退化。重構就是在不改變代碼行為的前提下,對其進行一系列小的改造,旨在改進系統結構的實踐活動。每個改造都是微不足道的,幾乎不值得去做。但是所有的這些改造疊加在一起,就形成了對系統設計和構架顯著的改進。

在每次細微改造之後,我們都會運行單元測試以確保改造沒有造成任何破壞,然後再去做下一次改造。如此往復,周而復始。通過這種方式,我們可以在改造系統設計的同時,保持系統可以工作。

重構是持續進行的,而不是在項目結束時、發布版本時、疊代結束時甚至每天快下班時才進行的。重構是我們每隔一個小時或者半個小時就要去做的事情。通過重構,我們可以持續地保持代碼儘可能乾淨、簡單並且具有表達力。

1.1.14隱喻

隱喻(metaphor)是唯一一個不具體、不直接的XP實踐,也是所有XP實踐中最難理解的一個。極限編程者在本質上都是務實主義者,隱喻這個缺乏具體定義的概念使我們覺得很不舒服。的確,一些XP的支持者經常討論把隱喻從XP的實踐中去除。然而,在某種意義上,隱喻卻是XP所有實踐中最重要的實踐之一。

想像一下智力拼圖玩具。你怎樣知道如何把各個小塊拼在一起?顯然,每一塊都與其他塊相鄰,並且它的形狀必須與相鄰的塊完美地吻合。如果你眼睛看不見但是具有很好的觸覺,那麼通過鍥而不捨地篩選每個小塊,不斷地嘗試它們的位置,也能夠拼出整個圖形。

但是,相對於各個小塊的形狀而言,還有一種更為強大的力量把這些複雜的小塊拼裝在一起。這就是整張拼圖的圖案。圖案是真正的嚮導。它的力量是如此之大,以至於如果圖案中相鄰的兩塊不具有互相吻合的形狀,那麼你就可以斷定拼圖玩具的製作者把玩具做錯了。

這就是隱喻。它是將整個系統聯繫在一起的全局視圖。它是系統的願景,是它使得所有單獨模塊的位置和外觀變得明顯直觀。如果模塊的外觀與整個系統的隱喻不符,那麼你就知道該模塊是錯誤的。

隱喻通常可以歸結為一個名字系統。這些名字提供了一個系統組成元素的詞彙表,並且有助於定義它們之間關係。

例如,我曾經開發過一個以每秒60個字符的速度將文本輸出到屏幕的系統。以這樣的速度,字符充滿整個屏幕需要一段時間。所以我們讓產生文本的程序把產生的文本放到一個緩衝區中。當緩衝區滿了的時候,我們把該程序交換到磁碟上。當緩衝區快要變空時,我們把該程序交換回來並讓它繼續運行。

我們用裝卸卡車拖運垃圾來比喻整個系統。緩衝區是小卡車。屏幕是垃圾場。程序是垃圾製造者。所有的名字相互吻合,這有助於我們從整體上去考慮系統。

舉另一個例子,我曾經開發過一個分析網絡流量的系統。每30分鐘,系統會輪詢幾十個網絡適配器,並從中獲取監控數據。每個網絡適配器為我們提供一小塊由幾個單獨變量組成的數據。我們稱這些數據塊為"麵包切片"。這些麵包切片是待分析的原始數據。分析程序"烤制"這些切片,因而被稱為"烤麵包機"。我們把數據塊中的單個變量稱為"麵包屑"。總之,它是一個有用並且有趣的隱喻。

當然,隱喻不僅僅是一個名字系統。隱喻是系統的願景,它指導著所有開發者去選擇合適的名字,把函數放到合適的位置,創建出新的合適的類和方法,等等。

1.2結論

極限編程是一組簡單、具體的實踐,這些實踐結合在一起形成了一個敏捷開發過程。極限編程是一種優良、通用的軟體開發方法。對於大多數項目團隊來說,可以拿來直接採用,也可以增加一些實踐,或者對其中的一些實踐進行修改後再採用。

光環國際PMI-ACP敏捷認證獨家學習培訓方案,敏捷實踐專家親臨授課

課前預習:預習制定學習資料,了解考試範圍和框架;班主任郵件、電話指導 預習;QQ群交流。

實戰精講解階段:敏捷課程Donmain I-VI實戰精講學習;組建EMBA學習小組,互相探討,結合老師的案例強化敏捷技術的應用。

全真模考:2天全真模考體驗,檢測學習成果;系統梳理考試知識點,全面解決考前疑難問題。

您可能感興趣
免責聲明:本文內容來源于光環國際,文章觀點不代表壹讀立場,如若侵犯到您的權益,或涉不實謠言,敬請向我們提出檢舉
最新文章 / 服務條款 / 私隱保護 / DMCA / 聯絡我們

壹讀/READ01.COM