淺談 eXtreme Programming, XP (極限開發/編程)
eXtreme Programming, XP 極限開發最早由 Kent Beck, Ward Cunnungham 與 Ron Jeffries 所提出,這樣的方法首次在 C3 (Chrysler Comprehensive Compensation System) 克萊斯勒綜合報酬系統的開發上使用,這個專案的負責人就是 Kent Beck。雖然 C3 這個專案並沒有獲得最後的成功,但是他們所提出的方法卻一直活躍在軟體開發的領域中。
XP 極限開發可以說是敏捷開發 (Agile Software Development) 中最受歡迎的一項手法。如果我們敏捷開發形容為絕世武功的心法,那麼 XP 就是練武的招式,這樣的概念也可以套用在CMMI(心法)這樣的軟體哲學上,更確切的說 XP 是一種軟體開發模式。
CMMI 適合在需求發展完整的軟體開發環境下執行,而 Agile 比較適合低成本與需求發展薄弱的環境 (像是台灣這樣的環境,客戶常常要求改東改西),雖兩者間許多概念背道而馳,但目的卻是一致的,就是想把事情做好!!
以目前的經驗來看,我實在沒能見過照著合約精神來完成開發的專案,同常為了要結案總有些拉扯,因此這樣的 XP 手法更符合多數開發者的需求。多說無益,親自體會比較重要。
XP 說實在蠻抽象的,就像是高喊民主自由的意識與主義,這樣的軟體開發哲學常常說了沒人懂,懂的人卻說不清楚。要導入這樣的開發理念,潛移默化會是比較好的方式,用體會來傳遞真理!?
XP Activities, 價值與核心概念介紹
XP 要傳遞的教義似乎有點抽象,可不是一本可蘭經或聖經就能夠表達,個人也不是體會很深,僅能帶給大家思考的動力。
首先先介紹 XP 定義的軟體開發的四種 Activities (基本行為)
- Coding
程式編碼,軟體開發的基本產出就是程式碼,而程式碼也是唯一重要的。這樣的定義似乎說明文件的地位是很低的,實際上我認為這是一種資訊隱藏技術,因為好的程式碼就是文件。
- Testing
軟體測試是非常重要的,如果沒有測試程式測過的程式碼,那就等於沒有程式碼。我想這是目前最缺乏的有效制度之一。
- Listening
頃聽客戶的實際需求,了解業務邏輯 (Business Logic) 需求背後的故事,持續地在程式設計師與客戶間進行溝通。我認為主要可以強化需求發展與需求變更。
- Designing
系統設計,你必須在系統設計上花心思,就算只把上述的工作做好,沒有好的系統設計,失敗將會是這個系統的命運。經過分析與設計的系統,子系統之間不會存在過多的相依性,我想這也是我們積極朝向的目標。
XP Values, 價值介紹
了解 XP 定義的軟體開發行為後,接這說明 XP 所帶來的 Values (價值)。
- Communication (溝通)
傳統的系統開法手法常需要定義許多需求規格文件 (所謂的需求規格書),但 XP 倡導程式設計師與需求提供者應該常常溝通 (口頭開會最好),透過簡單的文件與設計進行溝通,並且即時回饋。
- Simplicity (簡單就是美!?)
XP 鼓勵我們用簡單的方式完成工作,並且鼓勵不斷重構你的系統 (當然是在有完整單元測試的條件下)。我們將系統設計為簡單且容易理解,僅把今天的需求進行實作,而不要花時間去實做未來的需求,因為未來含有太多的變化風險。
XP Say : One is the commandment to always design and code for today and not for tomorrow.
sj Say : 今日事今日畢,明日事今不可畢!! (早點下班好....... ^^)
- Feedback (反饋機制)
Feedback from the system (來自系統的反饋)
透過單元測試,系同將能夠自動告訴你,當你修改程式碼後發生了甚麼事?
Feedback from the customer (來自客戶的反饋)
透過功能性測試讓客戶了解系統的開發進度,同常2, 3個禮拜進行一次評估 (類似專案管理中的專案會議)。
Feedback from the team (來自團隊的反饋)
來自客戶的新需求透過開發小組的討論後,即可評估出新需求所需要的工作時間,並且回饋給客戶。
- Courage (勇氣)
勇氣,這是我最欣 賞的一項作風,也是優異的系統能夠付予的優點。什麼是勇氣呢?我認為勇氣就是信任,你必須信任這一套機制而不會讓你在改寫程式碼後遭到客 戶追殺,你必須勇敢的 Refactoring (重構) 你的系統,而隨時可以用更好的設計來改寫你的系統。也呼應上述提到的 Simplicity,避免程式設計師掉入系統設計架構的迷失。更確切的說,假設你今天為了給一個功能,一直思考這樣改可能會影響到其他功 能,那樣改又覺得程式碼很骯髒,想了半天卻還在這樣處理過程中徘徊,又想起當初根本不應該這樣設計系統,如果當初將系統設計成另一種優異的架構,我現在就 不會這麼煩惱了。如果你有這種想法,那提起勇氣 Refactoring (重構)吧!Refactoring 重構並不是 Reworking 重工,重構將能夠改善與提升你的系統品質(如果設計正確的話.......-_-)。
sj : 相信自己,勇敢的改寫你的系統吧!(改壞了別怪我.......)
- Respect (尊重)
這個項目是 eXtreme Programming 第二版才提出的項目,其中談到程式設計師的尊重與自重。XP 雖然倡導程式是團隊的,歡迎任何成員進行修改,但程式設計師應該為自己 commit 到版本控制系統中的程式碼負責,不應該 commit 會造成測試失敗的程式碼。
我個人倒是覺得在開發階段造成測試案例失敗是正常的,但是利用自動化的系統反饋機制 (Feedback from the system) 來掌控缺失也是一個好方法,不然因為硬碟壞掉又沒有 commit 造成的煩惱而吐血可就得不償失了,因此開發階段多多 Commit 吧。
XP Principles, 原則要領
- Feedback 快速反饋
在如此的開發環境下,對於需求所進行的程式碼修改,須能夠透過單元測試快速地反饋,所謂的反饋就是這樣的程式變更對系統會造成什麼樣的影響。當然反饋的過程中為了達到快速,而採用自動化的測試機制是必要的,因此在實做的過程中會導入 Continuous Integration (持續整合) 來輔助進行。
- Assuming simplicity 極簡風格
在這個原則中倡導每個需求都用最簡單的方式完成,而不需要考慮未來的擴充性。但是我認為這是不容易達成的,因為我們在撰寫程式碼的同時都會很直覺性的思考設計的問題,好的設計可以獲得更容易維護的系統是不變的道理。
- Embracing change 包容變化
所謂的包容變化指的是對於客戶需求變更我們應該接受,但當然在成本不得提升或另行報價的情況來看會比較實際,總不能需求無限創意無限。不然這樣的話 RD 將會加班無限,生命有限!
XP Practices, 實踐要領
上述提了這麼多抽象裡面,總該講些實際應用的手法吧?畢竟只有心法是不夠的,諸如此類的軟體工程總要 "說的一套,做的一套" 。所謂說的一套是指概念,做的一套是指做法,就像很多公司花大錢請 CMMI 導入顧問來指導實際做法,其目的通常是為了取得那張紙。
XP 說明了實踐的4項範圍,其中包含了12項作業,主架構有點類似 CMMI 的做法,我們就來繼續介紹吧,至少這邊的內容比起上面算是最實際的,也是花大錢請來的顧問在指導的方針。
1. Fine scale feedback
- Pair programming 結隊程式設計
這個翻譯實在 很.......阿六仔,其實就是兩個人一起寫code啦。通常公司聽到這點就怕了,原本一個人做的事現在要兩個人做,大多出來的成本誰負 責!? 其實這個概念很有趣,XP 相信兩個人寫出來的 Code 會相當完美,且品質很高,通常可以一個寫程式一個負責監督(笑他或電他),無形中就在測試了。而兩個人的角色也可以互換,甚至 Team 中的成員輪流替換。這樣的概念其實有很多好處,也可以讓大家都知道程式的細節,避免開發人員流失對專案造成過大的風險。
甲工程師 (拼命寫程式)
乙工程師笑他:你這樣寫不好,你應該這樣寫比較聰明。
上述的過程就是測試與Code Review
- Test-driven development 測試驅動開發
這個好啊,但是很 難做。第一次有人叫我這樣寫程式的時候,我心想 "我程式都寫不完了你還叫我寫測試!!我寫測試的時間比我寫程式還久!!莊孝維......." ,但是現在看到別人程式有問題自己都不知道的時候就可以問他:你都沒有測試嗎?他就會回答:我那時候是好的啊,不知道改到什麼,也不知道什麼時候功能不運 作了。這樣的故事告訴我們:羅馬不是一天造成的。但是講到寫測試的痛苦,實在一言難盡。要推行 TDD 是很不容易的,首先要建立完善的測試環境,還要熟悉一套好用的測試框架,最重要的一點:你要能夠透過測試帶給程式設計師愉快的心情!(我稱為反饋的喜悅,或者失敗反饋的恥辱)
要怎麼實行,透過持續整合的便利性是最好的途徑,先想辦法讓你的團隊成員慢慢體會測試吧,拿著棍子鞭打是沒用的,測是必須發自內心撰寫出來(我也還在努力中.......-_-)。
兩句測試殺人口訣:
A. 沒有測試程式的程式不是程式
B. 不寫測試不寫程式
- Whole team 全隊
指的是需要客戶與開發團隊一起共同進行開發 (敏捷開發也提到了這項要素),這個也是很多情況下無法實踐的項目,客戶通常只會在開會的時候電你。
- Planning game 策劃遊戲
策劃遊戲主要分成 兩個部分,Release Planning (發佈計畫) 與 Iteration Planning (反覆計畫)。這項工作其實骨子裡就是 RD, Requirement Development (CMMI的最愛!?) 需求發展,XP 所提到的 Planning Game 相當複雜,但有助於專案管理的進行,為什麼會這樣說呢?因為在這個工作完成後會產生許多工作項目(像是WBS工作包),在 XP 中稱為 Story,然而在傳統的 SA/SD 終究是交給 Use-Case 來扮演的角色。我只能大致以外行的角色介紹一下:
Release Planning (發佈計畫)
- Exploration phase (探索階段)
- Write a Story : 設計與撰寫情境,比如登入系統這樣的功能。
- Estimate a Story : 使用您豐富的經驗估計這個 Story 需要多少時間才可以完成。
- Split a Story : 如果某些 Stroy 工時過長,那麼請切割它吧。
- Commitment phase (承諾階段)
- Sort by Value : 將每一個 Story 進行權重分配 (做的事與CMMI的規格需求差不多),可分為 Critical, Significant Business Value, Nice to have 三項 (CMMI可以分的更細)。
- Sort by Risk : 就是專案管理的風險定性分析囉,XP 期望我們對 Story 進行 Completeness, Volatility, Complexity 三項以 0-2 的數字來設定,最後再計算風險索引 (專案管理人員一定不陌生)。
- Set Velocity : 決定用什麼樣的速度來開發。
- Choose scope : 講好下一次 Release 要完成哪些 Story。
這裡要做的事情其實就是將 Story 進行量化。
- Steering phase (監督階段)
對我來說就是專案執行與控制,當初估算的工期可能有出入,或者你的客戶需求每日一變,這些都是可以接受的 (如果不虧錢!!),好好的監督吧。我認為這的階段的重點就是:掌握好軟體開發節奏。
Iteration Planning (反覆計畫)
- Exploration phase (探索階段)
- Translate the requirement to tasks : 簡單的說就是派工
- Combine/Split task : 處理可能合併或切割的任務
- Estimate task : 預測任務的處理時間
- Commitment phase (承諾階段)
- A programmer accepts a task : 程式設計師來接任務
- Programmer estimates the task : 既然要接也要聲明交付時間
- Set load factor : 設定負載係數,有點像是實際工時 (我覺得沒必要)
- Balancing : 就是專案管理中的資源調配
- Steering phase (監督階段)
- Get a task card : 取得工作卡
- Find a Partner : 尋找你的另一半 (Pair programming)
- Design the task : 與你的伙伴一同設計功能
- Write unit test : 撰寫單元測試
- Write code : 寫code
- Run test : 執行測試
- Refactor : 改善你的程式碼
- Run Functional test : 執行功能測試 (通常交由QA來執行)
策劃遊戲介紹完了,果然複雜吧,但是這邊的內容也算是包含了許多 XP 的重要概念。
2. Continuous process
- Continuous integration
持續整合算是結合上述許多 XP 理念的重要實做,目的在於隨時 (當程式Commit) 進行整合測試,提早發現問題。對於持續整合的詳細介紹,可參考另一篇文章【持續整合介紹】。
- Design improvement
因為 XP 所提倡的 "今日事僅今日畢" 開發做法,如此常常會造成一些現象,例如系統很多不同的 Function 在做同一件事,或者含有很多骯髒的程式碼,甚至缺乏設計的演算法。當你碰到這樣的情況時就開始 Refactor (重構) 你的系統吧。
- Small releases
小規模的 Release 你的系統,在一定的短週期內將已經可以運作的功能進行 Release,如此能夠有效獲得客戶的信任,客戶會感覺開發團隊一直都有產出。
3. Shared understanding
- Coding standard
建立良好的程式撰寫標準,這樣的好處為程式碼整齊一致,當別人想要修改的你程式碼也能輕易上手。除了訂定程式撰寫標準外,也盡力維持一貫設計風格與 Design Pattern。
當你在訂定程式撰寫規範時,請務必參考程式語言的慣例,可別自行創造撰寫規範。
- Collective code ownership
程式碼是大家共有的,每一位程式設計師都要對所有程式負責,當然也可以任意修改程式,儘管這行程式不是你自己寫的。Pair programming 是有助於實現 Collective code ownership 的一項途徑,同時實踐效果更好。
- Simple design
採用最簡單容易明白的設計,當你撰寫一段程式碼時,你必須承認這是一段容易理解的程式碼,假設不是,那麼請 Refactor 吧。
- System metaphor
你的系統會說話!這邊的意思就是利用程式語言的特型,讓任何人可以從你的程式碼看出個所以然,更甚者能夠舉一反三。要實踐這樣的理念可以透過一些小技巧,比如類別名稱的命名、函式名稱的定義、變數名稱的定義等等。
4. Programmer welfare
- Sustainable pace
這邊提到軟體設計師的福利,真是太人性化了,其中提倡每一周工作時數不得超過40小時,採用緩慢的步伐開發系統,可以獲得品質更高與更有創新價值的程式碼。這些前提必須在有良好與完整的軟體測試、持續整合與佈署等等條件下,透過每天晚上或每個週末來進行自動化的工作。
5. 延伸實踐 (在第二版提出的項目)
別鬧了,還有喔.......這些是在第二版才提出的,如果想要走向 X (極致) 可參考一下吧。
- 開發人員和客戶之間的交互與溝通是有益的
- 如果學習是好的,那麼就把它做好吧
- 簡單的程式碼更可以完成工作
- 如果簡單的程式碼是好的,那麼把變得複雜的程式碼改寫成簡單的
- 程式碼評審 (Code Review) 是好的
- 撰寫測試程式是好的
心得
軟體工程門派百百種,我相信沒有一種軟體開發模式是完全符合你的工作環境,取捨實踐會是一個不錯的方式。從眾多門派中歸納出適合自己的法則才是最重要的,避免讓這樣的方法論又邁上一張紙 (CMMI證書) 的命運。
7 comments for “軟體開發之極限編程(極限開發) eXtreme Programming, XP”