极限编程

极限编程（英語：Extreme programming，縮寫為XP），是一种软件工程方法学，是敏捷软件开发的一种方式。如同其他敏捷方法学，极限编程和传统方法学的本质不同在于它更强调可适应性而不是可预测性。極限编程的支持者认为软件需求的不断变化是很自然的现象，是软件项目开发中不可避免的、也是应该欣然接受的现象；他们相信，和传统的在项目起始阶段定义好所有需求再费尽心思的控制变化的方法相比，有能力在项目周期的任何阶段去适应变化，将是更加现实更加有效的方法。 極限编程为管理人员和开发人员开出了一剂指导日常实践的良方；这个实践意味着接受并鼓励某些特别的有价值的方法。支持者相信，这些在传统的软件工程中看来是“极端的”实践，将会使开发过程比传统方法更加好的响应用户需求，因此更加敏捷，更好的构建出高质量软件。 极限编程的创始者是肯特·貝克、沃德·坎宁安和罗恩·杰弗里斯（英语：Ron Jeffries），他们在为克莱斯勒综合报酬系统（英语：Chrysler Comprehensive Compensation System）的薪水册项目工作时提出了极限编程方法。肯特·貝克在1996年3月成为克莱斯勒系统的项目负责人，开始对项目的开发方法学进行改善。他写了一本关于这个改善后的方法学的书，并且于1999年10月将之发行，这就是《极限编程解析》（2005第二版出版）。克莱斯勒在2000年2月取消了实质上并未成功的克莱斯勒系统，但是这个方法学却一直流行在软件工程领域中。直到2006年，很多软件开发项目都一直以极限编程做为他们的指导方法学。 該書闡述了如下的極限编程的哲學思想： 一種社會性的變化機制 一種開發模式 一種改進的方法 一種協調生產率和人性的嘗試 一種軟體開發方法 把极限编程一般化并用于其它型別的专案称为极限专案管理。 极限编程的推广之一为把不同的敏捷软件实践和传统实践节奏地结合起来，弹性地合用于不同企业开发环境。这就是软件开发节奏（Software Development Rhythms）的中心思想 極限编程的主要目標在於降低因需求變更而帶來的成本。在傳統系統開發方法中，系統需求是在專案開發的開始階段就確定下來，並在之後的開發過程中保持不變的。這意味著專案開發進入到之後的階段時出現的需求變更（而這樣的需求變更在一些發展極快的領域中是不可避免的）將導致開發成本急速增加。 極限编程透過引入基本價值、原則、方法等概念來達到降低變更成本的目的。一個應用了極限编程方法的系統開發專案在應對需求變更時將顯得更為靈活。 極限编程實踐作業的核心可以被區分為以下四個範圍（12個實踐作業）: 結對程式設計 策劃遊戲 測試驅動開發 全隊（原名：在場客戶） 持續整合 設計最佳化（原名：軟體重構） 小型發佈 編碼標準 程式碼集體共有 簡單設計 系統隱喻 可持之以恆的速度 在第二版的《極限編程解析》中，在主要實踐之外，還列出了一系列延伸的實踐。 核心實踐源自被廣泛接受的最佳實踐，並且被推向極致： 开发人员和客户之间的交互是有益的。因此，一个极限编程的小组从理论上要求需要一个软件使用者在身边，这个使用者制定软件的工作需求和优先等级，并且尽可能在各种问题出现的时候马上就能回答（实际工作中，这个角色是由客户代理商完成的）. 如果学习是好的，那么就把它做到底：这样减少了开发和回馈周期的长度，测试也能更早完成。 简单的代码更可能工作。所以极限编程的程序设计师在一个软件专案中唯写出能够满足目前实际需求的代码，这样或多或少降低了代码的复杂性和重复性。 如果简单的代码是好的，那么把变得复杂的代码改写成简单的。 代码评审是好的。因此，极限编程的程序设计师以两人搭档的方式工作。他们共享一个屏幕和键盘，增加了队员之间的交流，也让代码在一被写出的时候就被人评审了。 测试代码是好的。因此，在极限编程中，测试用例在实际代码之前就被写出来了。代码只有在通过测试的时候才被认为完成了。（当然，需要进一步分解来降低复杂性）。整个软件系统用一种周期化的，实时的，被预先编好的自动化测试方式来保证它的确有作用。参看测试驱动的开发。 一般来说，极限编程被认为对于少于12人的小团队很有用。一些人认为极限编程可以用于大的团队，但是其它人认为Rational统一过程更适合大的团队。然而，极限编程很难在一些超过100人的开发小组中获得成功。并不是极限编程不能够推广到更大的团队，而是很少有更大的团队来试著用它。极限编程的人员也拒绝去随便推测这个问题。 极限编程描述了在软件开发过程中四种基本的行为，包括 編碼 測試 傾聽 設計 極限编程的提倡者争辩说在系统开发过程的产物中真正重要的只有编码，并认为沒有經過測試的程式碼什麼都不是。如果你沒有測試，客戶可能感覺不到，很多軟體在發佈的時候沒有經過完整的測試，它們還都在工作（或多或少的工作）。極限编程認為，在軟體開發程序中，如果一個函數沒有經過測試就不能認為它可以工作。 极限编程技术以溝通、簡單、回饋、勇氣和尊重为价值标准。 构建一个软件系统的基本任务之一就是与系统的开发者交流以明确系统的具体需求。在一些正式的软件开发方法中，这一任务是通过文档来完成的。 极限编程技术可以被看成是在开发小组的成员之间迅速构建与传播制度上的认识的一种方法。它的目标是向所有开发人员提供一个对于系统的共享的视角，而这一视角又是与系统的最终用户的视角相吻合的。为了达到这一目标，极限编程支持设计、抽象、还有用户-程序员间交流的简单化，鼓励经常性的口头交流与回馈。 极限编程鼓励从最简单的解决方式入手再通过不断重构达到更好的结果。这种方法与传统系统开发方式的不同之处在于，它只关注于对当前的需求来进行设计、编码，而不去理会明天、下周或者下个月会出现的需求。极限编程的拥护者承认这样的考虑是有缺陷的，即有时候在修改现有的系统以满足未来的需求时不得不付出更多的努力。然而他们主张“不对将来可能的需求上投入精力”所得到的好处可以弥补这一点，因为将来的需求在他们还没提出之前是很可能发生变化的。为了将来不确定的需求进行设计以及编码意味着在一些可能并不需要的方面浪费资源。而与之前提到的“交流”这一价值相关联来看，设计与代码上的简化可以提高交流的质量。一个由简单的编码实现的简单的设计可以更加容易得被小组中的每个程序员所理解。 在极限编程中，“回饋”是和系统开发的很多不同方面相关联的： 来自系统的回饋：通过编写单元测试，程序员能够很直观的得到经过修改后系统的状态。 来自客户的回饋：功能性测试是由客户还有测试人员来编写的。他们能由此得知当前系统的状态。这样的评审一般计划2、3个礼拜进行一次，这样客户可以非常容易的了解、掌控开发的进度。 来自小组的回饋：当客户带着新需求来参加项目计划会议时，小组可以直接对于实现新需求所需要的时间进行评估然后回饋给客户。 回饋是与“交流”、“简单”这两条价值紧密联系的。为了沟通系统中的缺陷，可以通过编写单元测试，简单的证明某一段代码存在问题。来自系统的直接回饋信息将提醒程序员注意这一部分。用户可以以定义好的功能需求为依据，对系统进行周期性的测试。用Kent Beck的话来说：“编程中的乐观主义是危险的，而及时回饋则是解决它的方法。” 极限编程理论中的“系统开发中的勇气”最好用一组实践来诠释。其中之一就是“只为目前的需求设计以及编码，別为不可预期的未来做太多考虑”这条戒律。这是努力避免陷入设计的泥潭、而在其他问题上花费了太多不必要的精力。勇气使得开发人员在需要重构他们的代码时能感到舒适。这意味着重新审查现有系统并完善它会使得以后出现的变化需求更容易被实现。另一个勇气的例子是了解什么时候应该完全丢弃现有的代码。每个程序员都有这样的经历：他们花了一整天的时间纠缠于自己设计和代码中的一个复杂的难题却无所得，而第二天回来以一个全新而清醒的角度来考虑，在半小时内就轻松解决了问题。 尊重的价值体现在很多方面。在极限编程中，团队成员间的互相尊重体现在每个人保证提交的任何改变不会导致编译无法通过、或者导致现有的测试案例失败、或者以其他方式导致工作延期。团队成员对于他们工作的尊重体现在他们总是坚持追求高质量，坚持通过重构的手段来为手头的工作找到最好的解决设计方案。 组成极限编程基础的原则，正是基于上面描述的那几条价值。在系统开发项目中，这些原则被用来为决策做出指导。与价值相比，原则被描述的更加具体化，以便在实际应用中更为简单的转变为具体的指导意见。 当回馈能做到及时、迅速，将发挥极大的作用。一个事件和对这一事件做出回饋之间的时间，一般被用来掌握新情况以及做出修改。与传统开发方法不同，与客户的发生接触是不断反复出现的。客户能够清楚地洞察开发中系统的状况。他／她能够在整个开发过程中及时给出回饋意见，并且在需要的时候能够掌控系统的开发方向。 单元测试同样对贯彻回饋原则起到作用。在编写代码的过程中，应需求变更而做出修改的系统将出现怎样的反应，正是通过单元测试来给出直接回饋的。比如，某个程序员对系统中的一部分代码进行了修改，而假如这样的修改影响到了系统中的另一部分（超出了这个程序员的可控范围），则这个程序员不会去关注这个缺陷。往往这样的问题会在系统进入生产环节时暴露出来。 假設簡單認為任何問題都可以"極度簡單"地解決。傳統的系統開發方法要考慮未來的變化，要考慮程式碼的可重用性。極限編程拒絕這樣做。 可以肯定地是，不确定因素总是存在的。“包容变化”这一原则就是强调不要对变化采取反抗的态度，而应该包容它们。比如，在一次阶段性会议中客户提出了一些看来戏剧性的需求变更。作为程序员，必须包容这些变化，并且拟定计划使得下一个阶段的产品能够满足新的需求。 在極限编程中主要的策劃程序稱為策劃遊戲，本節將通過程序模型介紹這個程序。 策劃程序分為兩部分： 發佈策劃： 反覆狀態： 這一階段涉及成本、利潤和計劃影響這三個因素，包含四個部分： 按照價值排序：業務方按照商業價值為使用者故事排序。 按風險排序：開發方按風險為使用者故事排序。 設定周轉率：開發方決定以怎樣的速度開展專案。 選擇範圍：挑選在下一個發佈中需要被完成的使用者故事，基於使用者故事決定發佈日期。 業務方按照商業價值為使用者故事排序。它們會被分為三類： 關鍵：沒有這些故事系統無法運作或變得毫無意義。 重要的商業價值：有重要業務價值的非關鍵使用者故事。 最好能有：並沒有重要商業價值的使用者故事；例如在可用性或使用者界面上的改進。 程式設計師按照風險對使用者故事進行排序。他／她們將使用者故事的風險劃分成三類：低、中、高。以下是這種方式的一個範例： 決定風險索引：依照以下因素給每個使用者故事一個0到2的索引： 完全度（我們是否已經瞭解所有的故事細節？） 完全（0） 不完全（1） 未知（2） 發散性（可能會發生變化嗎？） 低（0） 中（1） 高（2） 複雜度（是否難以建構？） 簡單（0） 標準（1） 複雜（2） 為每個使用者故事增加所有這些索引後，給這些使用者故事指定一個風險索引：低（0–1），中（2–4），高（5–6）。 在作業階段開發人員和業務人員可以「操縱」整個程序。這意味著，他們可以做出改變。個體的使用者故事，或是不同使用者故事的相對優先等級，都有可能改變；預估時間也可能出現誤差。這是做出相應調整的機會。 反覆計劃中的探索階段是關於建立任務和預估實施時間。 收集使用者故事：收集並編輯下一個發佈的所有使用者故事。 組合／分割任務：如果程式設計師因為任務太大或太小而不能預估任務完成時間，則需要組合或分割此任務。 預估任務：預測需要實作此任務的時間。 在反覆計劃的約定階段以不同使用者故事作為參考的任務被指派到程式設計師。 程式設計師接受任務：每個程式設計師都挑選一個他／她負責的任務。 程式設計師預估任務：由於程式設計師對此任務負責，他／她必須給出一個完成任務的估計時間。 設定負載係數：負載係數表示每個程式設計師在一個反覆中理想的開發時間。比如：一周工作40小時，其中5小時用於開會，則負載係數不會超過35小時。 平衡：當團隊中所有程式設計師都已經被配置了任務，便會在預估時間和負載係數間做出比較。任務配置在程式設計師中達到平衡。如果有一個程式設計師的開發任務過重，其它程式設計師必須接手他／她的一部分任務，反之亦然。 各個任務是在反覆計劃的作業階段中一步步實作的。 取得一張任務卡片：程式設計師取得一張由他／她負責的任務的卡片。 找尋一名同伴：這個程式設計師將和另一位程式設計師一同完成開發工作。這在實施結隊程式設計中會做更深入的探討。 設計這個任務：如果需要，兩位程式設計師會設計這個任務所達成的功能。 編輯單元測試：在程式設計師開始編輯實作功能的程式碼之前，他／她們首先編輯自動測試。這在實施單元測試中會做更深入的探討。 編輯程式碼：兩位程式設計師開始編輯程式碼。 執行測試：執行單元測試來確定程式碼能正常工作。 執行功能測試：執行功能測試（基於相關使用者故事和任務卡片中的需求）。 結對程式設計的意思是所有的程式碼都是由兩個人坐在一台電腦前一起完成的。一個程式設計師控制電腦並且主要考慮編碼細節。另外一個人主要關注整體結構，不斷的對第一個程式設計師寫的程式碼進行評審。 結對不是固定的：我們甚至建議程式設計師盡量交叉結對。這樣，每個人都可以知道其它人的工作，每個人都對整個系統熟悉，結對程式設計加強了團隊內的溝通。（這與程式碼集體所有制是息息相關的）. 集體所有制意味著每個人都對所有的程式碼負責；這一點，反過來又意味著每個人都可以更改程式碼的任意部分。結隊程式設計對這一實踐貢獻良多：借由在不同的結隊中工作，所有的程式設計師都能看到完全的程式碼。集體所有制的一個主要優勢是提升了開發程序的速度，因為一旦程式碼中出現錯誤，任何程式設計師都能修正它。 在給予每個開發人員修改程式碼的權限的情況下，可能存在程式設計師引入錯誤的風險，他／她們知道自己在做什麼，卻無法預見某些依賴關係。完善的單元測試可以解決這個問題：如果未被預見的依賴產生了錯誤，那麼當單元測試執行時，它必定會失敗。 在極限編程中，「客戶」並不是為系統付帳的人，而是真正使用該系統的人。極限編程認為客戶應該時刻在現場解決問題。例如：在團隊開發一個財務管理系統時，開發小組內應包含一位財務管理人員。 單元測試是用以測試一小段程式碼的自動測試（例如：類，方法）。在極限編程中，在程式碼編輯前就編輯單元測試。這種方式的目的是激勵程式設計師設想他／她的程式碼在何種條件下會出錯。極限編程認為當程式設計師無法再想出更多能使他／她的程式碼出錯的情況時，這些程式碼便算完成。 由於極限编程教條提倡編輯程式時只滿足目前的需求，並且以盡可能簡單的方式實作。有時會碰上一套僵硬的系統，所謂僵硬的系統，表現之一是需要雙重（或多重）維護：功能變化需要對多份同樣（或類似）的程式碼進行修改；另一種表現是對程式碼的一部分進行修改時會影響其它很多部分。XP教條認為當這種情況發生時，意味著系統正告訴你通過改變系統架構以重構程式碼，使它更簡單、更泛用。參見重構。 極限編程方法的基本特徵是： 增量和反覆式的開發 - 一次小的改進跟著一個小的改進。 反覆性，通常是自動重複的單元測試，回歸測試。參見JUnit。 結對程式設計 在程式設計團隊中的使用者交互（在場的客戶） 軟體重構 共享的程式碼所有權 簡單 回饋 用隱喻來組織系統 可以忍受的速度 極限编程也有其被爭論的一面： 沒有書面的詳細的規格說明書 客戶代表被安排在專案中 程式設計師以結對的方式工作 測試驅動的開發 絕大多數設計活動都匆匆而過，並漸進式的，開始一個「最簡單的可能工作的東西」並當其需要時（測試失敗）才增加複雜性。單元測試促成為了設計紀律。 Extreme programming explained 《极限编程解析》第二版 書籍 肯特·貝克：《極致編程解析：擁抱變化》，Addison-Wesley, ISBN 0201616416 阿里斯代爾·寇本：《敏捷軟體開發》，Addison-Wesley, ISBN 0201699699 雷劍文：《超越傳統的軟體開發——極致編程的幻象與真實》，電子工業出版社，ISBN 7-121-00657-X Lui, Kim Man 雷劍文, Software Development Rhythms: Harmonizing Agile Practices for Synergy, John Wiley and Sons, 2008（http://as.wiley.com/WileyCDA/WileyTitle/productCd-0470073861.html） Ken Auer and Roy Miller. Extreme Programming Applied: Playing To Win, Addison–Wesley. Ken Auer; Ron Jeffries; Jeff Canna; Glen B. Alleman; Lisa Crispin; Janet Gregory. Are Testers eXtinct? How Can Testers Contribute to XP Teams?. Springer-Verlag. 2002. doi:10.1007/3-540-45672-4_50.  Kent Beck: Extreme Programming Explained: Embrace Change, Addison–Wesley. Kent Beck and Martin Fowler: Planning Extreme Programming, Addison–Wesley. Kent Beck and Cynthia Andres. Extreme Programming Explained: Embrace Change, Second Edition, Addison–Wesley. Alistair Cockburn: Agile Software Development, Addison–Wesley. Martin Fowler: Refactoring: Improving the Design of Existing Code, Addison–Wesley. Harvey Herela (2005). Case Study: The Chrysler Comprehensive Compensation System. Galen Lab, U.C. Irvine. Jim Highsmith. Agile Software Development Ecosystems, Addison–Wesley. Ron Jeffries, Ann Anderson and Chet Hendrickson (2000), Extreme Programming Installed, Addison–Wesley. Craig Larman & V. Basili (2003). "Iterative and Incremental Development: A Brief History", Computer (IEEE Computer Society) 36 (6): 47–56. Matt Stephens and Doug Rosenberg (2003). Extreme Programming Refactored: The Case Against XP, Apress. Waldner, JB. (2008). "Nanocomputers and Swarm Intelligence". In: ISTE, 225–256. 沃德·坎寧安的網站，極致編程 （页面存档备份，存于互联网档案馆），關於極致編程和相關主題的更多資訊。 面對客戶的極致編程介紹 羅恩·傑弗裡斯的網路雜誌XProgramming.com - 極致編程資源 （页面存档备份，存于互联网档案馆） ExtremeProgramming.org （页面存档备份，存于互联网档案馆） 馬特斯蒂芬斯的批評網站，對極致編程的問題的深邃的批評（參見該頁得到更多對極致編程的批評的連結） 馬丁·福勒論極致編程 搭檔編程，極致編程實踐 敏捷軟體開發的宣言 （页面存档备份，存于互联网档案馆） 工具："XPlanner" 工具："XPWeb （页面存档备份，存于互联网档案馆）" 來自CiteSeer的引文 （页面存档备份，存于互联网档案馆） 來自方法與工具 （页面存档备份，存于互联网档案馆）雜誌的文章脫離極致編程的極致編程測試：利用敏捷測試實踐的優勢 （页面存档备份，存于互联网档案馆） 來自方法與工具 （页面存档备份，存于互联网档案馆）雜誌的文章結對程式設計真能改進你的專案？ （页面存档备份，存于互联网档案馆）