高效程序員的45個習(xí)慣(敏捷開發(fā)指南)_第1頁
高效程序員的45個習(xí)慣(敏捷開發(fā)指南)_第2頁
高效程序員的45個習(xí)慣(敏捷開發(fā)指南)_第3頁
高效程序員的45個習(xí)慣(敏捷開發(fā)指南)_第4頁
高效程序員的45個習(xí)慣(敏捷開發(fā)指南)_第5頁
已閱讀5頁,還剩96頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

高效程序員的45個習(xí)慣敏捷開發(fā)指南目錄\h第1章敏捷——高效軟件開發(fā)之道\h第2章態(tài)度決定一切\(zhòng)h1做事\h2欲速則不達\h3對事不對人\h4排除萬難,奮勇前進\h第3章學(xué)無止境\h5跟蹤變化\h6對團隊投資\h7懂得丟棄\h8打破砂鍋問到底\h9把握開發(fā)節(jié)奏\h第4章交付用戶想要的軟件\h10讓客戶做決定\h11讓設(shè)計指導(dǎo)而不是操縱開發(fā)\h12合理地使用技術(shù)\h13保持可以發(fā)布\h14提早集成,頻繁集成\h15提早實現(xiàn)自動化部署\h16使用演示獲得頻繁反饋\h17使用短迭代,增量發(fā)布\h18固定的價格就意味著背叛承諾\h第5章敏捷反饋\h19守護天使\h20先用它再實現(xiàn)它\h21不同環(huán)境,就有不同問題\h22自動驗收測試\h23度量真實的進度\h24傾聽用戶的聲音\h第6章敏捷編碼\h25代碼要清晰地表達意圖\h26用代碼溝通\h27動態(tài)評估取舍\h28增量式編程\h29保持簡單\h30編寫內(nèi)聚的代碼\h31告知,不要詢問\h32根據(jù)契約進行替換\h第7章敏捷調(diào)試\h33記錄問題解決日志\h34警告就是錯誤\h35對問題各個擊破\h36報告所有的異常\h37提供有用的錯誤信息\h第8章敏捷協(xié)作\h38定期安排會面時間\h39架構(gòu)師必須寫代碼\h40實行代碼集體所有制\h41成為指導(dǎo)者\h42允許大家自己想辦法\h43準(zhǔn)備好后再共享代碼\h44做代碼復(fù)查\h45及時通報進展與問題\h第9章尾聲:走向敏捷\h9.1只要一個新的習(xí)慣\h9.2拯救瀕臨失敗的項目\h9.3引入敏捷:管理者指南\h9.4引入敏捷:程序員指南\h9.5結(jié)束了嗎\h附錄A資源\h索引第1章敏捷——高效軟件開發(fā)之道不管路走了多遠,錯了就要重新返回。——土耳其諺語這句土耳其諺語的含義顯而易見,你也會認(rèn)同這是軟件開發(fā)應(yīng)該遵守的原則。但很多時候,開發(fā)人員(包括我們自己)發(fā)現(xiàn)自己走錯路后,卻不愿意立即回頭,而是抱著遲早會步入正軌的僥幸心理,繼續(xù)錯下去。人們會想,或許差不多少吧,或許錯誤不像想象的那么嚴(yán)重。假使開發(fā)軟件是個確定的、線性的過程,我們隨時可以撤回來,如同諺語中所說的那樣。然而,它卻不是。相反,軟件開發(fā)更像是在沖浪——一直處于動態(tài)、不斷變化的環(huán)境中。大海本身無法預(yù)知,充滿風(fēng)險,并且海里還可能有鯊魚出沒。沖浪之所以如此有挑戰(zhàn)性,是因為波浪各不相同。在沖浪現(xiàn)場,每次波浪都是獨一無二的,沖浪的動作也會各不相同。例如,沙灘邊的波浪和峭壁下的波浪就有很大的區(qū)別。在軟件開發(fā)領(lǐng)域里,在項目研發(fā)過程中出現(xiàn)的需求變化和挑戰(zhàn)就是你在沖浪時要應(yīng)對的海浪——它們從不停止并且永遠變化,像波浪一樣。在不同的業(yè)務(wù)領(lǐng)域和應(yīng)用下,軟件項目具有不同的形式,帶來了不同的挑戰(zhàn)。甚至還有鯊魚以各種偽裝出沒。軟件項目的成敗,依賴于整個項目團隊中所有開發(fā)成員的技術(shù)水平,對他們的培訓(xùn),以及他們各自的能力高低。就像成功的沖浪手一樣,開發(fā)人員必須也是技術(shù)扎實、懂得掌握平衡和能夠敏捷行事的人。不管是預(yù)料之外的波浪沖擊,還是預(yù)想不到的設(shè)計失敗,在這兩種情況下敏捷都意味著可以快速地適應(yīng)變化。敏捷開發(fā)宣言我們正通過親身實踐和幫助他人實踐,揭示了一些更好的軟件開發(fā)方法。通過這項工作,我們認(rèn)為:□個體和交互勝過過程和工具□可工作的軟件勝過面面俱到的文檔□客戶協(xié)作勝過合同談判□響應(yīng)變化勝過遵循計劃雖然右項也有價值,但我們認(rèn)為左項具有更大的價值。敏捷宣言作者,2001年版權(quán)所有。更多詳細信息可以訪問。敏捷的精神那么,到底什么是敏捷開發(fā)方法?整個敏捷開發(fā)方法的運動從何而來呢?2001年2月,17位志愿者(包括作者之一Andy在內(nèi))聚集在美國猶他州雪鳥度假勝地,討論一個新的軟件開發(fā)趨勢,這個趨勢被不嚴(yán)格地稱為“輕量型軟件開發(fā)過程”。我們都見過了因為開發(fā)過程的冗余、笨重、繁雜而失敗的項目。世上應(yīng)該有一種更好的軟件開發(fā)方法——只關(guān)注真正重要的事情,少關(guān)注那些占用大量時間而無甚裨益的不重要的事情。這些志愿者們給這個方法學(xué)取名為敏捷。他們審視了這種新的軟件開發(fā)方法,并且發(fā)布了敏捷開發(fā)宣言:一種把以人為本、團隊合作、快速響應(yīng)變化和可工作的軟件作為宗旨的開發(fā)方法(本頁最開始的方框里就是宣言的內(nèi)容)。敏捷方法可以快速地響應(yīng)變化,它強調(diào)團隊合作,人們專注于具體可行的目標(biāo)(實現(xiàn)真正可以工作的軟件),這就是敏捷的精神。它打破了那種基于計劃的瀑布式軟件開發(fā)方法,將軟件開發(fā)的實際重點轉(zhuǎn)移到一種更加自然和可持續(xù)的開發(fā)方式上。它要求團隊中的每一個人(包括與團隊合作的人)都具備職業(yè)精神,并積極地期望項目能夠獲得成功。它并不要求所有人都是有經(jīng)驗的專業(yè)人員,但必須具有專業(yè)的工作態(tài)度——每個人都希望盡最大可能做好自己的工作。如果在團隊中經(jīng)常有人曠工、偷懶甚至直接怠工,那么這樣的方法并不適合你,你需要的是一些重量級的、緩慢的、低生產(chǎn)率的開發(fā)方法。如果情況并非如此,你就可以用敏捷的方式進行開發(fā)。這意味著你不會在項目結(jié)束的時候才開始測試,不會在月底才進行一次系統(tǒng)集成,也不會在一開始編碼的時候就停止收集需求和反饋。相反,這些活動會貫穿項目的整個生命周期。事實上,只要有人繼續(xù)使用這個軟件,開發(fā)就沒有真正結(jié)束。我們進行的是持續(xù)開發(fā)、持續(xù)反饋。你不需要等到好幾個月之后才發(fā)現(xiàn)問題:越早發(fā)現(xiàn)問題,就越容易修復(fù)問題,所以應(yīng)該就在此時此刻把問題修復(fù)。開發(fā)要持續(xù)不斷,切勿時續(xù)時斷Continuousdevelopment,notepisodic這就是敏捷的重點所在。這種持續(xù)前進的開發(fā)思想根植于敏捷方法中。它不但應(yīng)用于軟件開發(fā)的生命周期,還應(yīng)用于技術(shù)技能的學(xué)習(xí)、需求采集、產(chǎn)品部署、用戶培訓(xùn)等方面。它包括了軟件開發(fā)各個方面的所有活動。為什么要進行持續(xù)開發(fā)呢?因為軟件開發(fā)是一項非常復(fù)雜的智力活動,你遺留下來的任何問題,要么僥幸不會發(fā)生意外,要么情況會變得更糟糕,慢慢惡化直到變得不可控制。當(dāng)問題累積到一定程度的時候,事情就更難解決,最后無法扭轉(zhuǎn)。面對這樣的問題,唯一有效的解決辦法就是持續(xù)地推進系統(tǒng)前進和完善(見《程序員修煉之道》一書中的“軟件熵”[HT00])。持續(xù)注入能量Injectenergy有些人對使用敏捷方法有顧忌,認(rèn)為它只是另一種危機管理而已。事實并非如此。危機管理是指問題累積并且惡化,直到它們變得非常嚴(yán)重,以至于你不得不立即放下一切正在做的工作來解決危機。而這樣又會帶來其他的負(fù)面影響,你就會陷入危機和恐慌的惡性循環(huán)中。這些正是你要避免的問題。所以,你要防微杜漸,把問題解決在萌芽狀態(tài),你要探索未知領(lǐng)域,在大量成本投入之前先確定其可行性。你要知錯能改,在事實面前主動承認(rèn)自己的所有錯誤。你要能自我反省,經(jīng)常編碼實戰(zhàn),加強團隊協(xié)作精神。一開始你可能會覺得不適應(yīng),因為這同以往有太多的不同,但是只要能真正地行動起來,習(xí)慣了,你就會得心應(yīng)手。敏捷的修煉之道下面一句話是對敏捷的精辟概括。敏捷開發(fā)就是在一個高度協(xié)作的環(huán)境中,不斷地使用反饋進行自我調(diào)整和完善。下面將扼要講述它的具體含義,以及敏捷的團隊?wèi)?yīng)該采取什么樣的工作和生活方式。首先,它要整個團隊一起努力。敏捷團隊往往是一個小型團隊,或者是大團隊分成的若干小團隊(10人左右)。團隊的所有成員在一起工作,如果可能,最好有獨立的工作空間(或者類似bullpen\h[1]),一起共享代碼和必要的開發(fā)任務(wù),而且大部分時間都能在一起工作。同時和客戶或者軟件的用戶緊密工作在一起,并且盡可能早且頻繁地給他們演示最新的系統(tǒng)。你要不斷從自己寫的代碼中得到反饋,并且使用自動化工具不斷地構(gòu)建(持續(xù)集成)和測試系統(tǒng)。在前進過程中,你都會有意識地修改一些代碼:在功能不變的情況下,重新設(shè)計部分代碼,改善代碼的質(zhì)量。這就是所謂的重構(gòu),它是軟件開發(fā)中不可或缺的一部分——編碼永遠沒有真正意義上的“結(jié)束”。要以迭代的方式進行工作:確定一小塊時間(一周左右)的計劃,然后按時完成它們。給客戶演示每個迭代的工作成果,及時得到他們的反饋(這樣可以保證方向正確),并且根據(jù)實際情況盡可能頻繁地發(fā)布系統(tǒng)版本讓用戶使用。對上述內(nèi)容有了了解之后,我們會從下面幾個方面更深入地走進敏捷開發(fā)的實踐。第2章:態(tài)度決定一切。軟件開發(fā)是一項智力勞動。在此章,我們會講解如何用敏捷的心態(tài)開始工作,以及一些有效的個人習(xí)慣。這會為你使用敏捷方法打下扎實的基礎(chǔ)。第3章:學(xué)無止境。敏捷項目不可能坐享其成。除了開發(fā)之外,我們還要在幕后進行其他的訓(xùn)練,雖然它不屬于開發(fā)工作本身,但卻對團隊的發(fā)展極其重要。我們還將看到,如何通過培養(yǎng)習(xí)慣來幫助個人和團隊成長并自我超越。第4章:交付用戶想要的軟件。如果軟件不符合用戶的需求,無論代碼寫得多么優(yōu)美,它都是毫無用處的。這里將會介紹一些客戶協(xié)作的習(xí)慣和技巧,讓客戶一直加入到團隊的開發(fā)中,學(xué)習(xí)他們的業(yè)務(wù)經(jīng)驗,并且保證項目符合他們的真正需求。第5章:敏捷反饋。敏捷團隊之所以能夠順利開展工作,而不會陷入泥潭掙扎導(dǎo)致項目失敗,就是因為一直使用反饋來糾正軟件和開發(fā)過程。最好的反饋源自代碼本身。本章將研究如何獲得反饋,以及如何更好地控制團隊進程和性能。第6章:敏捷編碼。為滿足將來的需求而保持代碼的靈活和可變性,這是敏捷方法成功的關(guān)鍵。本章給出了一些習(xí)慣,介紹如何讓代碼更加整潔,具有更好的擴展性,防止代碼慢慢變壞,最后變得不可收拾。第7章:敏捷調(diào)試。調(diào)試錯誤會占用很多項目開發(fā)的時間——時間是經(jīng)不起浪費的。這里將會學(xué)到一些提高調(diào)試效率的技巧,節(jié)省項目的開發(fā)時間。第8章:敏捷協(xié)作。最后,一個敏捷開發(fā)者已經(jīng)能夠獨擋一面,除此之外,你需要一個敏捷團隊。這里有一些最有效的實踐有助于黏合整個團隊,以及其他一些實踐有助于團隊日常事務(wù)和成長。敏捷工具箱全書中,我們會涉及一些敏捷項目常用的基本工具。也許一些工具你還很陌生,所以這里做了簡單介紹。想要了解這些工具的詳細信息,可以進一步去讀附錄中的有關(guān)參考文獻。Wiki:Wiki\h[2]是一個網(wǎng)站,用戶通過瀏覽器,就可以編輯網(wǎng)頁內(nèi)容并創(chuàng)建鏈接到一個新的內(nèi)容頁面。Wiki是一種很好的支持協(xié)作的工具,因為團隊中的每一個人都可以根據(jù)需要動態(tài)地新增和重新組織網(wǎng)頁中的內(nèi)容,實現(xiàn)知識共享。關(guān)于Wiki的更多詳情,可查閱《Wiki之道》這篇文章[LC01]。版本控制:項目開發(fā)中所有的產(chǎn)物——全部的源代碼、文檔、圖標(biāo)、構(gòu)建腳本等,都需要放入版本控制系統(tǒng)中,由版本控制系統(tǒng)來統(tǒng)一管理。令人驚訝的是,很多團隊仍然喜歡把這些文件放到一個網(wǎng)絡(luò)上共享的設(shè)備上,但這是一種很不專業(yè)的做法。如果需要一個安裝和使用版本控制系統(tǒng)的詳細說明,可以查閱《版本控制之道——使用CVS》[TH03]或者《版本控制之道——使用Subversion》[Mas05]。單元測試:用代碼來檢查代碼,這是開發(fā)者獲得反饋的主要來源。在本書后面會更多地談到它,但要真正知道框架可以處理大部分的繁瑣工作,讓你把精力放到業(yè)務(wù)代碼的實現(xiàn)中。想要了解單元測試,可以看《單元測試之道Java版》[HT03]和《單元測試之道C#版》[HT04],你可以在《JUnitRecipes中文版》[Rai04]一書中找到很多寫單元測試的實用技巧。自動構(gòu)建:不管是在自己的本地機器上實現(xiàn)構(gòu)建,還是為整個團隊實現(xiàn)構(gòu)建,都是全自動化并可重復(fù)的。因為這些構(gòu)建一直運行,所以又稱為持續(xù)集成。和單元測試一樣,有大量的免費開源產(chǎn)品和商業(yè)產(chǎn)品為你提供支持?!俄椖孔詣踊馈穂Cla04]介紹了所有自動構(gòu)建的技巧和訣竅(包括使用JavaLamps)。最后,ShipIt![RG05]一書很好地介紹了怎樣將這些基本的開發(fā)環(huán)境實踐方法結(jié)合到一起。魔鬼和這些討厭的細節(jié)如果你翻翻這本書就會注意到,在每節(jié)的開頭我們都會引入一段話,旁邊配有一個魔鬼木刻像,誘使你養(yǎng)成不良習(xí)慣,如下所示?!案砂?,就走那個捷徑。真的,它可以為你節(jié)省時間。沒有人會知道是你干的,這樣你就會加快自己的開發(fā)進度,并且能夠完成這些任務(wù)了。這就是關(guān)鍵所在?!彼挠行┰捖犐先ビ悬c兒荒唐,就像是ScottAdams筆下呆伯特(Dilbert)漫畫書中的魔王——“尖發(fā)老板”所說的話一樣。但要記住Adams先生可是從他那些忠實的讀者中得到很多回饋的。有些事情看上去就會讓人覺得很怪異,但這全部是我們親耳所聞、親眼所見,或者是大家秘而不宣的事情,它們都是擺在我們面前的誘惑,不管怎樣,只要試過就會知道,為了節(jié)省項目的時間而走愚蠢的捷徑是會付出巨大代價的。與這些誘惑相對,在每個習(xí)慣最后,會出現(xiàn)一位守護天使,由她給出我們認(rèn)為你應(yīng)該遵循的一些良策。先難后易。我們首先要解決困難的問題,把簡單的問題留到最后?,F(xiàn)實中的事情很少是黑白分明的。我們將用一些段落描述一個習(xí)慣應(yīng)該帶給你什么樣的切身感受,并介紹成功實施和保持平衡的技巧。如下所示。切身感受本段描述培養(yǎng)某個習(xí)慣應(yīng)該有什么樣的切身感受。如果在實踐中沒有這樣的體會,你就要考慮改變一下實施的方法。平衡的藝術(shù)□一個習(xí)慣很可能會做得過火或者做得不夠。我們會給出一些建議,幫你掌握平衡,并告訴你一些技巧,能使習(xí)慣真正為你所用。畢竟,一件好事做得過火或者被誤用,都是非常危險的(我們見過很多所謂的敏捷項目最后失敗,都是因為團隊在實踐的時候沒有保持好自己的平衡)。所以,我們希望保證你能真正從這些習(xí)慣中獲益。通過遵循這些習(xí)慣,把握好平衡的藝術(shù),在真實世界中有效地應(yīng)用它們,你將會看到你的項目和團隊發(fā)生了積極的變化。好了,你將步入敏捷開發(fā)者的修煉之路,更重要的是,你會理解其后的開發(fā)原則。致謝每本書的出版都是一項艱巨的事業(yè),本書也不例外。除了作者,還有很多幕后英雄。我們要感謝下面所有的人,正是他們的幫助,本書才得以問世。感謝JimMoore為本書設(shè)計的封面插圖,感謝KimWimpsett出色的文字編輯工作(如果還有錯,那肯定是最后一刻的修改導(dǎo)致的)。最后感謝所有付出時間和精力讓本書變得更好的審閱者:MarcusAhnve、EldonAlameda、SergeiAnikin、MatthewBass、DavidBock、A.LesterBuckIII、BrandonCampbell、ForrestChang、MikeClark、JohnCook、EdGibbs、DaveGoodlad、RamamurthyGopalakrishnan、MartyHaught、JackHerrington、RonJeffries、MatthewJohnson、JasonHiltzLaforge、ToddLittle、TedNeward、JamesNewkirk、JaredRichardson、FrédérickRos、BillRushmore、DavidLázaroSaz、NateSchutta、MattSecoske、GuerrySemones、BrianSletten、MikeStok、StephenViles、LeifWickland和JoeWinter。VenkatSubramaniam致謝我要感謝DaveThomas,他是我的良師益友。如果沒有他的指導(dǎo)、鼓勵和建設(shè)性的意見,本書到現(xiàn)在還只是一個空想。我有幸與AndyHunt合著本書,從他身上學(xué)到了太多的東西。他不僅是一位技術(shù)專家(任何注重實效的程序員都知道這一點),還具有令人難以置信的表達能力和優(yōu)秀品質(zhì)。我欣賞PragmaticProgrammers出版公司制作本書的每一個環(huán)節(jié),他們精通很多有用的工具,具有解決問題的能力,而且最重要的是,他們有很好的工作態(tài)度,正因如此,本書才可以如此順利地發(fā)布。感謝MarcGarbey的鼓勵。他是一位偉大的朋友,他的幽默和敏捷感染了世界上的很多人。我特別感謝那些與我一路同行的俗人們(錯了,是朋友們)——BenGalbraith、BrianSletten、BruceTate、DaveThomas、DavidGeary、DionAlmaer、EitanSuez、ErikHatcher、GlennVanderburg、HowardLewisShip、JasonHunter、JustinGehtland、MarkRichards、NealFord、RamnivasLaddad、ScottDavis、StuHalloway和TedNeward——這些家伙棒極了!我感謝JayZimmerman(人稱敏捷推動者),NFJS的主管,感謝他的鼓勵,感謝他給我機會去向他的客戶推廣我的敏捷思想。感謝父親教會我正確的人生價值觀,還有母親給予我創(chuàng)造的靈感。如果不是妻子Kavitha的耐心和鼓勵,還有我的兒子們Karthik和Krupakar的支持,我就沒有今天的一切。謝謝,我愛你們!AndyHunt致謝好的,我想現(xiàn)在每個人都被感謝過了。但是,我要特別感謝Venkat邀請我參與本書的寫作。我不會接受任何其他人要我合作寫這本書的邀請,但卻接受了Venkat的邀請。他最清楚整件事情的經(jīng)過。我要感謝當(dāng)年在雪鳥聚會的那些敏捷精英們。雖然沒有任何哪一個人發(fā)明了敏捷,但正是通過所有人的共同努力,才讓敏捷在當(dāng)今的軟件開發(fā)行業(yè)中茁壯成長,成為一支重要的力量。當(dāng)然,還要感謝我的家人,感謝他們的支持和理解。從最早的《程序員修煉之道》到現(xiàn)在這本書是一個漫長的征途,但也是一段開心的經(jīng)歷?,F(xiàn)在,演出開始了?!咀⑨尅縗h[1]bullpen原指在棒球比賽中,侯補投手的練習(xí)場?!g者注\h[2]WiKi是WikiWikiWeb的簡稱,WikiWiki源自夏威夷語,本意是快點快點。第2章態(tài)度決定一切選定了要走的路,就是選定了它通往的目的地?!狧arryEmersonFosdick(美國基督教現(xiàn)代主義神學(xué)家)傳統(tǒng)的軟件開發(fā)圖書一般先介紹一個項目的角色配置,然后是你需要產(chǎn)生哪些工件(artifact)——文檔、任務(wù)清單、甘特(Gantt)圖等,接著就是規(guī)則制度,往往是這么寫的:汝當(dāng)如此\h[1]這般……本書的風(fēng)格不是這樣的。歡迎進入敏捷方法的世界,我們的做法有些不同。例如,有一種相當(dāng)流行的軟件方法學(xué)要求對一個項目分配35種不同的角色,包括架構(gòu)師、設(shè)計人員、編碼人員、文檔管理者等。敏捷方法卻背道而馳。只需要一個角色:軟件開發(fā)者,也就是你。項目需要什么你就做什么,你的任務(wù)就是和緊密客戶協(xié)作,一起開發(fā)軟件。敏捷依賴人,而不是依賴于項目的甘特圖和里程表。圖表、集成開發(fā)環(huán)境或者設(shè)計工具,它們本身都無法產(chǎn)生軟件,軟件是從你的大腦中產(chǎn)生的。而且它不是孤立的大腦活動,還會有許多其他方面的因素:個人情緒、辦公室的文化、自我主義、記憶力等。它們混為一體,態(tài)度和心情的瞬息變化都可能導(dǎo)致巨大的差別。因此態(tài)度非常重要,包括你的和團隊的。專業(yè)的態(tài)度應(yīng)該著眼于項目和團隊的積極結(jié)果,關(guān)注個人和團隊的成長,圍繞最后的成功開展工作。由于很容易變成追求不太重要的目標(biāo),所以在本章,我們會專注于那些真正的目標(biāo)。集中精力,你是為做事而工作。(想知道怎樣做嗎?請見下一頁。)軟件項目時常伴有時間壓力——壓力會迫使你走捷徑,只看眼前利益。但是,任何一個有經(jīng)驗的開發(fā)者都會告訴你,欲速則不達(我們在第15頁將介紹如何避免這個問題)。我們每個人或多或少都有一些自我主義。一些人(暫且不提他們的名字)還美其名曰“健康”的自我主義。如果要我們?nèi)ソ鉀Q一個問題,我們會為完成任務(wù)而感到驕傲,但這種驕傲有時會導(dǎo)致主觀和脫離實際。你也很可能見過設(shè)計方案的討論變成了人身攻擊,而不是就事論事地討論問題。對事不對人(第18頁)會讓工作更加有效。反饋是敏捷的基礎(chǔ)。一旦你意識到走錯了方向,就要立即做出決策,改變方向。但是指出問題往往沒有那么容易,特別當(dāng)它涉及一些政治因素的時候。有時候,你需要勇氣去排除萬難,奮勇前進(第23頁)。只有在你對項目、工作、事業(yè)有一個專業(yè)的態(tài)度時,使用敏捷方法才會生效。如果態(tài)度不正確,那么所有的這些習(xí)慣都不管用。有了正確的態(tài)度,你才可以從這些方法中完全受益。下面我們就來介紹這些對你大有裨益的習(xí)慣和建議。1做事“出了問題,第一重要的是確定元兇。找到那個白癡!一旦證實了是他的錯誤,就可以保證這樣的問題永遠不會再發(fā)生了?!庇袝r候,這個老魔頭的話聽起來似乎很有道理。毫無疑問,你想把尋找罪魁禍?zhǔn)自O(shè)為最高優(yōu)先級,難道不是嗎?肯定的答案是:不。最高優(yōu)先級應(yīng)該是解決問題。也許你不相信,但確實有些人常常不把解決問題放在最高優(yōu)先級上。也許你也沒有。先自我反省一下,當(dāng)有問題出現(xiàn)時,“第一”反應(yīng)究竟是什么。如果你說的話只是讓事態(tài)更復(fù)雜,或者只是一味地抱怨,或者傷害了他人的感情,那么你無意中在給問題火上澆油。相反,你應(yīng)該另辟蹊徑,問問“為了解決或緩解這個問題,我能夠做些什么?”在敏捷的團隊中,大家的重點是做事。你應(yīng)該把重點放到解決問題上,而不是在指責(zé)犯錯者上面糾纏。世上最糟糕的工作(除了在馬戲團跟在大象后面打掃衛(wèi)生)就是和一群愛搬弄是非的人共事。他們對解決問題并沒有興趣,相反,他們愛在別人背后議論是非。他們挖空心思指手畫腳,議論誰應(yīng)該受到指責(zé)。這樣一個團隊的生產(chǎn)力是極其低下的。如果你發(fā)現(xiàn)自己是在這樣的團隊中工作,不要從團隊中走開——應(yīng)該跑開。至少要把對話從負(fù)面的指責(zé)游戲引到中性的話題,比如談?wù)擉w育運動(紐約揚基隊最近怎么樣)或者天氣。指責(zé)不能修復(fù)bugBlamedoesn’tfixbugs在敏捷團隊中,情形截然不同。如果你向敏捷團隊中的同事抱怨,他們會說:“好,我能幫你做些什么?”他們把精力直接放到解決問題上,而不是抱怨。他們的動機很明確,重點就是做事,不是為了自己的面子,也不是為了指責(zé),也無意進行個人智力角斗。你可以從自己先做起。如果一個開發(fā)者帶著抱怨或問題來找你,你要了解具體的問題,詢問他你能提供什么樣的幫助。這樣簡單的一個行為就清晰地表明你的目的是解決問題,而不是追究責(zé)任,這樣就會消除他的顧慮。你是給他們幫忙的。這樣,他們會知道每次走近你的時候,你會真心幫助他們解決問題。他們可以來找你把問題解決了,當(dāng)然還可以繼續(xù)去別處求助。符合標(biāo)準(zhǔn)不是結(jié)果許多標(biāo)準(zhǔn)化工作強調(diào)遵從一個過程,按符合的程度作評判,其理由是:如果過程可行,那么只要嚴(yán)格按這個過程行事,就不會有問題。但是,現(xiàn)實世界并不是如此運行的。你可以去獲得ISO-9001認(rèn)證,并生產(chǎn)出一件漂亮的鉛線織就的救生衣。你完全遵循了文檔中約定的過程,糟糕的是到最后所有的用戶都被淹死了。過程符合標(biāo)準(zhǔn)并不意味結(jié)果是正確的。敏捷團隊重結(jié)果勝于重過程。如果你找人幫忙,卻沒有人積極響應(yīng),那么你應(yīng)該主動引導(dǎo)對話。解釋清楚你想要什么,并清晰地表明你的目的是解決問題,而不是指責(zé)他人或者進行爭辯。指責(zé)不會修復(fù)bug。把矛頭對準(zhǔn)問題的解決辦法,而不是人。這是真正有用處的正面效應(yīng)。切身感受勇于承認(rèn)自己不知道答案,這會讓人感覺放心。一個重大的錯誤應(yīng)該被當(dāng)作是一次學(xué)習(xí)而不是指責(zé)他人的機會。團隊成員們在一起工作,應(yīng)互相幫助,而不是互相指責(zé)。平衡的藝術(shù)□“這不是我的錯”,這句話不對?!斑@都是你的錯”,這句話更不對?!跞绻銢]有犯過任何錯誤,就說明你可能沒有努力去工作。□開發(fā)者和質(zhì)量工程師(QA)爭論某個問題是系統(tǒng)本身的缺陷還是系統(tǒng)增強功能導(dǎo)致的,通常沒有多大的意義。與其如此,不如趕緊去修復(fù)它?!跞绻粋€團隊成員誤解了一個需求、一個API調(diào)用,或者最近一次會議做的決策,那么,也許就意味著團隊的其他成員也有相同的誤解。要確保整個團隊盡快消除誤解?!跞绻粋€團隊成員的行為一再傷害了團隊,則他表現(xiàn)得很不職業(yè)。那么,他就不是在幫助團隊向解決問題的方向前進。這種情況下,我們必須要求他離開這個團隊\h[2]。□如果大部分團隊成員(特別是開發(fā)領(lǐng)導(dǎo)者)的行為都不職業(yè),并且他們對團隊目標(biāo)都不感興趣,你就應(yīng)該主動從這個團隊中離開,尋找更適合自己發(fā)展的團隊(這是一個有遠見的想法,沒必要眼睜睜地看著自己陷入一個“死亡之旅”的項目中[You99])。2欲速則不達“你不需要真正地理解那塊代碼,它只要能夠工作就可以了。哦,它需要一個小小的調(diào)整。只要在結(jié)果中再加上幾行代碼,它就可以工作了。干吧!就把那幾行代碼加進去,它應(yīng)該可以工作?!蔽覀兘?jīng)常會遇到這種情況,出現(xiàn)了一個bug,并且時間緊迫??焖傩迯?fù)確實可以解決它——只要新加一行代碼或者忽略那個列表上的最后一個條目,它就可以工作了。但接下來的做法才能說明,誰是優(yōu)秀的程序員,誰是拙劣的代碼工人。拙劣的代碼工人會這樣不假思索地改完代碼,然后快速轉(zhuǎn)向下一個問題。優(yōu)秀的程序員會挖掘更深一層,盡力去理解為什么這里必須要加1,更重要的是,他會想明白會產(chǎn)生什么其他影響。也許這個例子聽起來有點做作,甚至你會覺得很無聊。但是,真實世界中有大量這樣的事情發(fā)生。Andy以前的一個客戶正遇到過這樣的問題。沒有一個開發(fā)者或者架構(gòu)師知道他們業(yè)務(wù)領(lǐng)域的底層數(shù)據(jù)模型。而且,通過幾年的積累,代碼里有著成千上萬的+1和-1修正。在這樣臟亂的代碼中添加新的功能或者修復(fù)bug,就難逃脫發(fā)的噩運(事實上,很多開發(fā)者因此而禿頂)。千里之堤,潰于蟻穴,大災(zāi)難是逐步演化來的。一次又一次的快速修復(fù),每一次都不探究問題的根源,久而久之就形成了一個危險的沼澤地,最終會吞噬整個項目的生命。在工作壓力之下,不去深入了解真正的問題以及可能的后果,就快速修改代碼,這樣只是解決表面問題,最終會引發(fā)大問題??焖傩迯?fù)的誘惑,很容易令人把持不住,墜入其中。短期看,它似乎是有效的。但從長遠來看,它無異于穿越一片流沙,你也許僥幸走過了一半的路程(甚至更遠),一切似乎都很正常。但是轉(zhuǎn)眼間悲劇就發(fā)生了……防微杜漸Bewareoflandmines只要我們繼續(xù)進行快速修復(fù),代碼的清晰度就不斷降低。一旦問題累積到一定程度,清晰的代碼就不復(fù)存在,只剩一片混濁。很可能在你的公司就有人這樣告訴你:“無論如何,千萬不能碰那個模塊的代碼。寫代碼那哥們兒已經(jīng)不在這兒了,沒有人看得懂他的代碼。”這些代碼根本沒有清晰度可言,它已經(jīng)成為一團迷霧,無人能懂。要理解開發(fā)過程盡管我們在談?wù)摾斫獯a,特別是在修改代碼之前一定要很好地理解它,然而同樣道理,你也需要了解團隊的開發(fā)方法或者開發(fā)過程。你必須要理解團隊采用的開發(fā)方法。你必須理解如何恰如其分地使用這種方法,為何它們是這樣的,以及如何成為這樣的。只有理解了這些問題,你才能進行有效的改變。如果在你的團隊中有這樣的事情發(fā)生,那么你是不可能敏捷的。但是敏捷方法中的一些技術(shù)可以阻止這樣的事情發(fā)生。這里只是一些概述,后面的章節(jié)會有更深入的介紹。孤立非常危險,不要讓開發(fā)人員完全孤立地編寫代碼(見第155頁,習(xí)慣40)。如果團隊成員花些時間閱讀其他同事寫的代碼,他們就能確保代碼是可讀和可理解的,并且不會隨意加入這些“+1或-1”的代碼。閱讀代碼的頻率越高越好。實行代碼復(fù)審,不僅有助于代碼更好理解,而且是發(fā)現(xiàn)bug最有效的方法之一(見第165頁,習(xí)慣44)。不要孤立地編碼Don’tcodeinisolation另一種防止代碼難懂的重要技術(shù)就是單元測試。單元測試幫助你很自然地把代碼分層,分成很多可管理的小塊,這樣就會得到設(shè)計更好、更清晰的代碼。更深入項目的時候,你可以直接閱讀單元測試——它們是一種可執(zhí)行的文檔(見第78頁,習(xí)慣19)。有了單元測試,你會看到更小、更易于理解的代碼模塊,運行和使用代碼,能夠幫助你徹底理解這些代碼。使用單元測試Useunittests不要墜入快速的簡單修復(fù)之中。要投入時間和精力保持代碼的整潔、敞亮。切身感受在項目中,代碼應(yīng)該是很亮堂的,不應(yīng)該有黑暗死角。你也許不知道每塊代碼的每個細節(jié),或者每個算法的每個步驟,但是你對整體的相關(guān)知識有很好的了解。沒有任何一塊代碼被警戒線或者“切勿入內(nèi)”的標(biāo)志隔離開。平衡的藝術(shù)□你必須要理解一塊代碼是如何工作的,但是不一定需要成為一位專家。只要你能使用它進行有效的工作就足夠了,不需要把它當(dāng)作畢生事業(yè)?!跞绻幸晃粓F隊成員宣布,有一塊代碼其他人都很難看懂,這就意味著任何人(包括原作者)都很難維護它。請讓它變得簡單些。□不要急于修復(fù)一段沒能真正理解的代碼。這種+1/-1的病癥始于無形,但是很快就會讓代碼一團糟。要解決真正的問題,不要治標(biāo)不治本?!跛械拇笮拖到y(tǒng)都非常復(fù)雜,因此沒有一個人能完全明白所有的代碼。除了深入了解你正在開發(fā)的那部分代碼之外,你還需要從更高的層面來了解大部分代碼的功能,這樣就可以理解系統(tǒng)各個功能塊之間是如何交互的?!跞绻到y(tǒng)的代碼已經(jīng)惡化,可以閱讀第23頁習(xí)慣4中給出的建議。3對事不對人你在這個設(shè)計上投入了很多精力,為它付出很多心血。你堅信它比其他任何人的設(shè)計都棒。別聽他們的,他們只會把問題變得更糟糕?!蹦愫芸赡芤娺^,對方案設(shè)計的討論失控變成了情緒化的指責(zé)——做決定是基于誰提出了這個觀點,而不是權(quán)衡觀點本身的利弊。我們曾經(jīng)參與過那樣的會議,最后鬧得大家都很不愉快。但是,這也很正常。當(dāng)Lee先生在做一個新方案介紹的時候,下面有人會說:“那樣很蠢!”(這也就暗示著Lee先生也很蠢。)如果把這句話推敲一下,也許會好一點:“那樣很蠢,你忘記考慮它要線程安全?!笔聦嵣献钸m合并且最有效的表達方式應(yīng)該是:“謝謝,Lee先生。但是我想知道,如果兩個用戶同時登錄會發(fā)生什么情況?”看出其中的不同了吧!下面我們來看看對一個明顯的錯誤有哪些常見的反應(yīng)?!醴穸▊€人能力?!踔赋雒黠@的缺點,并否定其觀點?!踉儐柲愕年犛眩⑻岢瞿愕念檻]。第一種方法是不可能成功的。即使Lee是一個十足的笨蛋,很小的問題也搞不定,但你那樣指出問題根本不會對他的水平有任何提高,反而會導(dǎo)致他以后再也不會提出自己的任何想法了。第二種方法至少觀點明確,但也不能給Lee太多的幫助,甚至可能會讓你自己惹火上身。也許Lee能巧妙地回復(fù)你對非線程安全的指責(zé):“哦,不過它不需要多線程。因為它只在Frozbot模塊的環(huán)境中使用,它已經(jīng)運行在自己的線程中了。”哎喲!忘記了Frozbot這一茬了?,F(xiàn)在該是你覺得自己蠢了,Lee也會因為你罵他笨蛋而生氣?,F(xiàn)在看看第三種方法。沒有譴責(zé),沒有評判,只是簡單地表達自己的觀點。讓Lee自己意識到這個問題,而不是掃他的面子\h[3]。由此可以開始一次交談,而不是爭辯。要專業(yè)而不是自我多年以前,在我擔(dān)任系統(tǒng)管理員的第一天,一位資深的管理員和我一起安裝一些軟件,我突然按錯了一個按鈕,把服務(wù)器給關(guān)掉了。沒過幾分鐘,幾位不爽的用戶就在敲門了。這時,我的導(dǎo)師贏得了我的信任和尊重,他并沒有指責(zé)我,而是對他們說:“對不起,我們正在查找是什么地方出錯了。系統(tǒng)會在幾分鐘之內(nèi)啟動起來?!边@讓我學(xué)到了難忘的重要一課。在一個需要緊密合作的開發(fā)團隊中,如果能稍加注意禮貌對待他人,將會有益于整個團隊關(guān)注真正有價值的問題,而不是勾心斗角,誤入歧途。我們每個人都能有一些極好的創(chuàng)新想法,同樣也會萌生一些很愚蠢的想法。如果你準(zhǔn)備提出一個想法,卻擔(dān)心有可能被嘲笑,或者你要提出一個建議,卻擔(dān)心自己丟面子,那么你就不會主動提出自己的建議了。然而,好的軟件開發(fā)作品和好的軟件設(shè)計,都需要大量的創(chuàng)造力和洞察力。分享并融合各種不同的想法和觀點,遠遠勝于單個想法為項目帶來的價值。負(fù)面的評論和態(tài)度扼殺了創(chuàng)新?,F(xiàn)在,我們并不提倡在設(shè)計方案的會議上手拉手唱《學(xué)習(xí)雷鋒好榜樣》,這樣也會降低會議的效率。但是,你必須把重點放在解決問題上,而不是去極力證明誰的主意更好。在團隊中,一個人只是智商高是沒有用的,如果他還很頑固并且拒絕合作,那就更糟糕。在這樣的團隊中,生產(chǎn)率和創(chuàng)新都會頻臨滅亡的邊緣。消極扼殺創(chuàng)新Negativitykillsinnovation我們每個人都會有好的想法,也會有不對的想法,團隊中的每個人都需要自由地表達觀點。即使你的建議不被全盤接受,也能對最終解決問題有所幫助。不要害怕受到批評。記住,任何一個專家都是從這里開始的。用LesBrown\h[4]的一句話說就是:“你不需要很出色才能起步,但是你必須起步才能變得很出色?!眻F體決策的駱駝集體決策確實非常有效,但也有一些最好的創(chuàng)新源于很有見地的個人的獨立思考。如果你是一個有遠見的人,就一定要特別尊重別人的意見。你是一個掌舵者,一定要把握方向,深思熟慮,吸取各方的意見。另一個極端是缺乏生氣的委員會,每個設(shè)計方案都需要全票通過。這樣的委員會總是小題大作,如果讓他們造一匹木馬,很可能最后造出的是駱駝。我們并不是建議你限制會議決策,只是你不應(yīng)該成為一意孤行的首席架構(gòu)師的傀儡。這里建議你牢記亞里士多德的一句格言:“能容納自己并不接受的想法,表明你的頭腦足夠有學(xué)識?!毕旅媸且恍┯行У奶厥饧夹g(shù)。設(shè)定最終期限。如果你正在參加設(shè)計方案討論會,或者是尋找解決方案時遇到問題,請設(shè)定一個明確的最終期限,例如午飯時間或者一天的結(jié)束。這樣的時間限制可以防止人們陷入無休止的理論爭辯之中,保證團隊工作的順利進行。同時(我們覺得)應(yīng)現(xiàn)實一些:沒有最好的答案,只有更合適的方案。設(shè)定期限能夠幫你在為難的時候果斷做出決策,讓工作可以繼續(xù)進行。逆向思維。團隊中的每個成員都應(yīng)該意識到權(quán)衡的必要性。一種客觀對待問題的辦法是:先是積極地看到它的正面,然后再努力地從反面去認(rèn)識它\h[5]。目的是要找出優(yōu)點最多缺點最少的那個方案,而這個好辦法可以盡可能地發(fā)現(xiàn)其優(yōu)缺點。這也有助于少帶個人感情。設(shè)立仲裁人。在會議的開始,選擇一個仲裁人作為本次會議的決策者。每個人都要有機會針對問題暢所欲言。仲裁人的責(zé)任就是確保每個人都有發(fā)言的機會,并維持會議的正常進行。仲裁人可以防止明星員工操縱會議,并及時打斷假大空式發(fā)言。如果你自己沒有積極參與這次討論活動,那么你最好退一步做會議的監(jiān)督者。仲裁人應(yīng)該專注于調(diào)停,而不是發(fā)表自己的觀點(理想情況下不應(yīng)在整個項目中有既得利益)。當(dāng)然,這項任務(wù)不需要嚴(yán)格的技術(shù)技能,需要的是和他人打交道的能力。支持已經(jīng)做出的決定。一旦方案被確定了(不管是什么樣的方案),每個團隊成員都必須通力合作,努力實現(xiàn)這個方案。每個人都要時刻記住,我們的目標(biāo)是讓項目成功滿足用戶需求。客戶并不關(guān)心這是誰的主意——他們關(guān)心的是,這個軟件是否可以工作,并且是否符合他們的期望。結(jié)果最重要。設(shè)計充滿了妥協(xié)(生活本身也是如此),成功屬于意識到這一點的團隊。工作中不感情用事是需要克制力的,而你若能展現(xiàn)出成熟大度來,大家一定不會視而不見。這需要有人帶頭,身體力行,去感染另一部分人。對事不對人。讓我們驕傲的應(yīng)該是解決了問題,而不是比較出誰的主意更好。切身感受一個團隊能夠很公正地討論一些方案的優(yōu)點和缺點,你不會因為拒絕了有太多缺陷的方案而傷害別人,也不會因為采納了某個不甚完美(但是更好的)解決方案而被人忌恨。平衡的藝術(shù)□盡力貢獻自己的好想法,如果你的想法沒有被采納也無需生氣。不要因為只是想體現(xiàn)自己的想法而對擬定的好思路畫蛇添足?!趺撾x實際的反方觀點會使?fàn)幷撟兾丁H魧σ粋€想法有成見,你很容易提出一堆不太可能發(fā)生或不太實際的情形去批駁它。這時,請先捫心自問:類似問題以前發(fā)生過嗎?是否經(jīng)常發(fā)生?□也就是說,像這樣說是不夠的:我們不能采用這個方案,因為數(shù)據(jù)庫廠商可能會倒閉?;蛘撸河脩艚^對不會接受那個方案。你必須要評判那些場景發(fā)生的可能性有多大。想要支持或者反駁一個觀點,有時候你必須先做一個原型或者調(diào)查出它有多少的同意者或者反對者?!踉陂_始尋找最好的解決方案之前,大家對“最好”的含義要先達成共識。在開發(fā)者眼中的最好,不一定就是用戶認(rèn)為最好的,反之亦然?!踔挥懈?,沒有最好。盡管“最佳實踐”這個術(shù)語到處在用,但實際上不存在“最佳”,只有在某個特定條件下更好的實踐。□不帶個人情緒并不是要盲目地接受所有的觀點。用合適的詞和理由去解釋為什么你不贊同這個觀點或方案,并提出明確的問題。4排除萬難,奮勇前進“如果你發(fā)現(xiàn)其他人的代碼有問題,只要你自己心里知道就可以了。畢竟,你不想傷害他們,或者惹來麻煩。如果他是你的老板,更要格外謹(jǐn)慎,只要按照他的命令執(zhí)行就可以了?!庇幸粍t寓言叫“誰去給貓系鈴鐺”(WhoWillBelltheCat)。老鼠們打算在貓的脖子上系一個鈴鐺,這樣貓巡邏靠近的時候,就能預(yù)先得到警報。每只老鼠都點頭,認(rèn)為這是一個絕妙的想法。這時一只年老的老鼠問道:“那么,誰愿意挺身而出去系鈴鐺呢?”毫無疑問,沒有一只老鼠站出來。當(dāng)然,計劃也就這樣泡湯了。有時,絕妙的計劃會因為勇氣不足而最終失敗。盡管前方很危險——不管是真的魚雷或者只是一個比喻——你必須有勇氣向前沖鋒,做你認(rèn)為對的事情。假如要你修復(fù)其他人編寫的代碼,而代碼很難理解也不好使用。你是應(yīng)該繼續(xù)修復(fù)工作,保留這些臟亂的代碼呢,還是應(yīng)該告訴你的老板,這些代碼太爛了,應(yīng)該通通扔掉呢?也許你會跳起來告訴周圍的人,那些代碼是多么糟糕,但那只是抱怨和發(fā)泄,并不能解決問題。相反,你應(yīng)該重寫這些代碼,并比較重寫前后的優(yōu)缺點。動手證明(不要只是嚷嚷)最有效的方式,是把糟糕的代碼放到一邊,立刻重寫。列出重寫的理由,會有助于你的老板(以及同事)認(rèn)清當(dāng)前形勢,幫助他們得到正確的解決方案。再假定你在處理一個特定的組件。突然,你發(fā)現(xiàn)完全弄錯了,你需要推翻重來。當(dāng)然,你也會很擔(dān)心向團隊其他成員說明這個問題,以爭取更多的時間和幫助。當(dāng)發(fā)現(xiàn)問題時,不要試圖掩蓋這些問題。而要有勇氣站起來,說:“我現(xiàn)在知道了,我過去使用的方法不對。我想到了一些辦法,可以解決這個問題——如果你有更好的想法,我也很樂意聽一聽——但可能會花多些時間?!蹦阋呀?jīng)把所有對問題的負(fù)面情緒拋諸腦后,你的意圖很清楚,就是尋找解決方案。既然你提出大家一起努力來解決問題,那就不會有任何爭辯的余地。這樣會促進大家去解決問題。也許,他們就會主動走近,提供幫助。更重要的是,這顯示出了你的真誠和勇氣,同時你也贏得了他們的信任。踐行良好習(xí)慣我曾經(jīng)開發(fā)過一個應(yīng)用系統(tǒng)。它向服務(wù)器程序發(fā)送不同類型的文件,再另存為另外一種格式的文件。這應(yīng)該不難。當(dāng)我開始工作的時候,我震驚地發(fā)現(xiàn),處理每種類型文件的代碼都是重復(fù)的。所以,我也配合了一下,復(fù)制了數(shù)百行的代碼,改變了其中的兩行代碼,幾分鐘之內(nèi)就讓它工作起來,但我卻感覺很失落。因為我覺得這有悖于良好的工作習(xí)慣。后來我說服了老板,告訴他代碼的維護成本很快就會變得非常高,應(yīng)該重構(gòu)代碼。一周之內(nèi),我們重構(gòu)了代碼,并立即由此受益,我們需要修改文件的處理方式,這次我們只需要改動一個地方就可以了,而不必遍查整個系統(tǒng)。你深知怎樣做才是正確的,或者至少知道目前的做法是錯誤的。要有勇氣向其他的項目成員、老板或者客戶解釋你的不同觀點。當(dāng)然,這并不容易。也許你會拖延項目的進度,冒犯項目經(jīng)理,甚至惹惱投資人。但你都要不顧一切,向著正確的方向奮力前進。美國南北戰(zhàn)爭時的海軍上將DavidFarragut曾經(jīng)說過一句名言:“別管他媽的魚雷,Drayton上校,全速前進?!贝_實,前面埋伏著水雷(那時叫魚雷),但是要突破防線,只有全速前進\h[6]。他們做得很對!做正確的事。要誠實,要有勇氣去說出實情。有時,這樣做很困難,所以我們要有足夠的勇氣。切身感受勇氣會讓人覺得有點不自在,提前鼓足勇氣更需要魄力。但有些時候,它是掃除障礙的唯一途徑,否則問題就會進一步惡化下去。鼓起你的勇氣,這能讓你從恐懼中解脫出來。平衡的藝術(shù)□如果你說天快要塌下來了,但其他團隊成員都不贊同。反思一下,也許你是正確的,但你沒有解釋清楚自己的理由?!跞绻阏f天快要塌下來了,但其他團隊成員都不贊同。認(rèn)真考慮一下,他們也許是對的。□如果設(shè)計或代碼中出現(xiàn)了奇怪的問題,花時間去理解為什么代碼會是這樣的。如果你找到了解決辦法,但代碼仍然令人費解,唯一的解決辦法是重構(gòu)代碼,讓它可讀性更強。如果你沒有馬上理解那段代碼,不要輕易地否定和重寫它們。那不是勇氣,而是魯莽。□當(dāng)你勇敢地站出來時,如果受到了缺乏背景知識的抉擇者的抵制,你需要用他們能夠聽懂的話語表達?!案逦拇a”是無法打動生意人的。節(jié)約資金、獲得更好的投資回報,避免訴訟以及增加用戶利益,會讓論點更有說服力?!跞绻阍趬毫ο乱獙Υa質(zhì)量作出妥協(xié),你可以指出,作為一名開發(fā)者,你沒有職權(quán)毀壞公司的資產(chǎn)(所有的代碼)?!咀⑨尅縗h[1]或更通俗地寫成:系統(tǒng)應(yīng)當(dāng)如何如何……。\h[2]不需要解雇他,但是他不能繼續(xù)留在這個項目中。同時也要意識到,頻繁的人員變動對整個團隊的平衡也很危險。\h[3]通常,這是一個很好的技巧:引導(dǎo)性地提出一個疑問,讓他們自己意識到問題。\h[4]萊斯·布朗,全球領(lǐng)軍勵志演講家和作家?!幷咦h[5]參見“DebatingwithKnives”,在/cgi-bin/pragdave.cgi/Random/FishBow1.rdoc。\h[6]事實上,F(xiàn)arragut的原話往往被簡化為:“別管他媽的魚雷,全速前進!”第3章學(xué)無止境即使你已經(jīng)在正確的軌道上,但如果只是停止不前,也仍然會被淘汰出局?!猈illRogers(美國著名演員)敏捷需要持續(xù)不斷的學(xué)習(xí)和充電。正如上面引用的WillRogers的話,逆水行舟,不進則退。那不僅是賽馬場上的真理,它更適合我們當(dāng)今的程序員。軟件開發(fā)行業(yè)是一個不停發(fā)展和永遠變化的領(lǐng)域。雖然有一些概念一直有用,但還有很多知識很快就會過時。從事軟件開發(fā)行業(yè)就像是在跑步機上,你必須一直跟上步伐穩(wěn)步前進,否則就會摔倒出局。誰會幫助你保持步伐前進呢?在一個企業(yè)化的社會中,只有一個人會為你負(fù)責(zé)——你自己。是否能跟上變化,完全取決于你自己。許多新技術(shù)都基于現(xiàn)有的技術(shù)和思想。它們會加入一些新的東西,這些新東西是逐步加入的量。如果你跟蹤技術(shù)變化,那么學(xué)習(xí)這些新東西對你來說就是了解這些增量變化。如果你不跟蹤變化,技術(shù)變化就會顯得很突然并且難以應(yīng)付。這就好比少小離家老大回,你會發(fā)現(xiàn)變化很大,甚至有很多地方都不認(rèn)識了。然而,居住在那里的人們,每天只看到小小的變化,所以非常適應(yīng)。在第28頁我們會介紹一些跟蹤變化的方法。給自己投資,讓自己與時俱進,當(dāng)然再好不過,但是也要努力對團隊投資,這個目標(biāo)怎么實現(xiàn)呢?你將從第31頁學(xué)到實現(xiàn)這個目標(biāo)的一些方法。學(xué)習(xí)新的技術(shù)和新的開發(fā)方法很重要,同時你也要能摒棄陳舊和過時的開發(fā)方法。換句話說,你需要懂得丟棄(請閱讀第34頁)。當(dāng)我們談到變化這個話題的時候,要認(rèn)識到你對問題的理解在整個項目期間也是在變化的。你曾經(jīng)認(rèn)為自己已經(jīng)很明白的事情,現(xiàn)在也許并不是你想象中那樣。你要對沒有完全理解的某些疑問不懈地深入追蹤下去,我們將從第37頁開始講述為什么要打破砂鍋問到底,以及如何有效地提問。最后,一個活力十足的敏捷開發(fā)團隊需要有規(guī)律反復(fù)地做很多事情,一旦項目開始運作,你就要把握開發(fā)節(jié)奏,我們會在第40頁介紹這種節(jié)奏感。5跟蹤變化“軟件技術(shù)的變化如此之快,勢不可擋,這是它的本性。繼續(xù)用你熟悉的語言做你的老本行吧,你不可能跟上技術(shù)變化的腳步?!焙绽死卣f過:“唯有變化是永恒的?!睔v史已經(jīng)證明了這句真理,在當(dāng)今快速發(fā)展的IT時代尤其如此。你從事的是一項充滿激情且不停變化的工作。如果你畢業(yè)于計算機相關(guān)的專業(yè),并覺得自己已經(jīng)學(xué)完了所有知識,那你就大錯特錯了。假設(shè)你是10多年前的1995年畢業(yè)的,那時,你掌握了哪些技術(shù)呢?可能你的C++還學(xué)得不錯,你了解有一門新的語言叫Java,一種被稱作是設(shè)計模式的思想開始引起大家的關(guān)注。一些人會談?wù)摫环Q作因特網(wǎng)的東東。如果那個時候你就不再學(xué)習(xí),而在2005年的時候重出江湖。再看看周圍,就會發(fā)現(xiàn)變化巨大。就算是在一個相當(dāng)狹小的技術(shù)領(lǐng)域,要學(xué)習(xí)那些新技術(shù)并達到熟練的程度,一年的時間也不夠。技術(shù)發(fā)展的步伐如此快速,簡直讓人們難以置信。就以Java為例,你掌握了Java語言及其一系列的最新特性。接著,你要掌握Swing、Servlet、JSP、Struts、Tapestry、JSF、JDBC、JDO、Hibernate、JMS、EJB、Lucene、Spring……還可以列舉很多。如果你使用的是微軟的技術(shù),要掌握VB、VisualC++、MFC、COM、ATL、.NET、C#、VB.NET、ASP.NET、ADO.NET、WinForm、EnterpriseService、Biztalk……并且,不要忘記還有UML、Ruby、XML、DOM、SAX、JAXP、JDOM、XSL、Schema、SOAP、WebService、SOA,同樣還可以繼續(xù)列舉下去(我們將會用光所有的縮寫字母)。不幸的是,如果只是掌握了工作中需要的技術(shù)并不夠。那樣的工作也許幾年之后就不再有了——它會被外包或者會過時,那么你也將會出局\h[1]。假設(shè)你是VisualC++或者VB程序員,看到COM技術(shù)出現(xiàn)了。你花時間去學(xué)習(xí)它(雖然很痛苦),并且隨時了解分布式對象計算的一切。當(dāng)XML出現(xiàn)的時候,你花時間學(xué)習(xí)它。你深入研究ASP,熟知如何用它來開發(fā)Web應(yīng)用。你雖然不是這些技術(shù)的專家,但也不是對它們一無所知。好奇心促使你去了解MVC是什么,設(shè)計模式是什么。你會使用一點Java,去試試那些讓人興奮的功能。如果你跟上了這些新技術(shù),接下來學(xué)習(xí).NET技術(shù)就不再是大問題。你不需要一口氣爬上10樓,而需要一直在攀登,所以最后看起來就像只要再上一二層。如果你對所有這些技術(shù)都一無所知,想要馬上登上這10樓,肯定會讓你喘不過氣來。而且,這也會花很長時間,期間還會有更新的技術(shù)出現(xiàn)。如何才能跟上技術(shù)變化的步伐呢?幸好,現(xiàn)今有很多方法和工具可以幫助我們繼續(xù)充電。下面是一些建議。迭代和增量式的學(xué)習(xí)。每天計劃用一段時間來學(xué)習(xí)新技術(shù),它不需要很長時間,但需要經(jīng)常進行。記下那些你想學(xué)習(xí)的東西——當(dāng)你聽到一些不熟悉的術(shù)語或者短語時,簡要地把它記錄下來。然后在計劃的時間中深入研究它。了解最新行情?;ヂ?lián)網(wǎng)上有大量關(guān)于學(xué)習(xí)新技術(shù)的資源。閱讀社區(qū)討論和郵件列表,可以了解其他人遇到的問題,以及他們發(fā)現(xiàn)的很酷的解決方案。選擇一些公認(rèn)的優(yōu)秀技術(shù)博客,經(jīng)常去讀一讀,以了解那些頂尖的博客作者們正在關(guān)注什么(最新的博客列表請參考)。參加本地的用戶組活動。Java、Ruby、Delphi、.NET、過程改進、面向?qū)ο笤O(shè)計、Linux、Mac,以及其他的各種技術(shù)在很多地區(qū)都會有用戶組。聽講座,然后積極加入到問答環(huán)節(jié)中。參加研討會議。計算機大會在世界各地舉行,許多知名的顧問或作者主持研討會或者課程。這些聚會是向?qū)<覍W(xué)習(xí)的最直接的好機會。如饑似渴地閱讀。找一些關(guān)于軟件開發(fā)和非技術(shù)主題的好書(我們很樂意為你推薦),也可以是一些專業(yè)的期刊和商業(yè)雜志,甚至是一些大眾媒體新聞(有趣的是在那里常常能看到老技術(shù)被吹捧為最新潮流)。跟蹤技術(shù)變化。你不需要精通所有技術(shù),但需要清楚知道行業(yè)的動向,從而規(guī)劃你的項目和職業(yè)生涯。切身感受你能嗅到將要流行的新技術(shù),知道它們已經(jīng)發(fā)布或投入使用。如果必須要把工作切換到一種新的技術(shù)領(lǐng)域,你能做到。平衡的藝術(shù)□許多新想法從未變得羽翼豐滿,成為有用的技術(shù)。即使是大型、熱門和資金充裕的項目也會有同樣的下場。你要正確把握自己投入的精力。□你不可能精通每一項技術(shù),沒有必要去做這樣的嘗試。只要你在某些方面成為專家,就能使用同樣的方法,很容易地成為新領(lǐng)域的專家?!跄阋靼诪槭裁葱枰@項新技術(shù)——它試圖解決什么樣的問題?它可以被用在什么地方?□避免在一時沖動的情況下,只是因為想學(xué)習(xí)而將應(yīng)用切換到新的技術(shù)、框架或開發(fā)語言。在做決策之前,你必須評估新技術(shù)的優(yōu)勢。開發(fā)一個小的原型系統(tǒng),是對付技術(shù)狂熱者的一劑良藥。6對團隊投資“不要和別人分享你的知識——自己留著。你是因為這些知識而成為團隊中的佼佼者,只要自己聰明就可以了,不用管其他失敗者?!眻F隊中的開發(fā)者們各有不同的能力、經(jīng)驗和技術(shù)。每個人都各有所長。不同才能和背景的人混在一起,是一個非常理想的學(xué)習(xí)環(huán)境。在一個團隊中,如果只是你個人技術(shù)很好還遠遠不夠。如果其他團隊成員的知識不夠,團隊也無法發(fā)揮其應(yīng)有的作用:一個學(xué)習(xí)型的團隊才是較好的團隊。當(dāng)開發(fā)項目的時候,你需要使用一些術(shù)語或者隱喻來清晰地傳達設(shè)計的概念和意圖。如果團隊中的大部分成員不熟悉這些,就很難進行高效地工作。再比如你參加了一個課程或者研討班之后,所學(xué)的知識如果不用,往往就會忘記。所以,你需要和其他團隊成員分享所學(xué)的知識,把這些知識引入團隊中。找出你或團隊中的高手擅長的領(lǐng)域,幫助其他的團隊成員在這些方面迎頭趕上(這樣做還有一個好處是,可以討論如何將這些東西應(yīng)用于自己的項目中)?!拔绮蜁h”是在團隊中分享知識非常好的方式。在一周之中挑選一天,例如星期三(一般來說任何一天都可以,但最好不要是星期一和星期五)。事先計劃午餐時聚集在一起,這樣就不會擔(dān)心和其他會議沖突,也不需要特別的申請。為了降低成本,就讓大家自帶午餐。每周,要求團隊中的一個人主持講座。他會給大家介紹一些概念,演示工具,或者做團隊感興趣的任何一件事情。你可以挑一本書,給大家說說其中一些特別內(nèi)容、項目或者實踐。\h[2]無論什么主題都可以。每個人都比你厲害嗎?嗯,那太好了!享有盛名的爵士吉他手PatMethany說過這樣一句話:“總是要成為你所在的那個樂隊中最差的樂手。如果你是樂隊中最好的樂手,就需要重新選擇樂隊了。我認(rèn)為這也適用于樂隊之外的其他事情?!睘槭裁词沁@樣呢?如果你是團隊中最好的隊員,就沒有動力繼續(xù)提高自己。如果周圍的人都比你厲害,你就會有很強的動力去追趕他們。你將會在這樣的游戲中走向自己的頂峰。從每周主持講座的人開始,先讓他講15分鐘,然后,進行開放式討論,這樣每個人都可以發(fā)表自己的意見,討論這個主題對于項目的意義。討論應(yīng)該包括所能帶來的益處,提供來自自己應(yīng)用程序的示例,并準(zhǔn)備好聽取進一步的信息。這些午餐會議非常有用。它促進了整個團隊對這個行業(yè)的了解,你自己也可以從其他人身上學(xué)到很多東西。優(yōu)秀的管理者會重用那些能提高其他團隊成員價值的人,因此這些活動也直接有助于你的職業(yè)生涯。提供你和團隊學(xué)習(xí)的更好平臺。通過午餐會議可以增進每個人的知識和技能,并幫助大家聚集在一起進行溝通交流。喚起人們對技術(shù)和技巧的激情,將會對項目大有裨益。切身感受這樣做,會讓每個人都覺得自己越來越聰明。整個團隊都要了解新技術(shù),并指出如何使用它,或者指出需要注意的缺陷。平衡的藝術(shù)□讀書小組逐章一起閱讀一本書,會非常有用,但是要選好書?!?天用設(shè)計模式和UML精通……》也許不會是一本好書?!醪皇撬械闹v座都能引人入勝,有些甚至顯得不合時宜。不管怎么樣,都要未雨綢繆;諾亞在建造方舟的時候,可并沒有開始下雨,誰能料到后來洪水泛濫呢?□盡量讓講座走入團隊中。如果午餐會議在禮堂中進行,有餐飲公司供飯,還要使用幻燈片,那么就會減少大家接觸和討論的機會?!鯃猿钟杏媱澯幸?guī)律地舉行講座。持續(xù)、小步前進才是敏捷。稀少、間隔時間長的馬拉松式會議非敏捷也?!跞绻恍﹫F隊成員因為吃午飯而缺席,用美食引誘他們?!醪灰窒抻诩兗夹g(shù)的圖書和主題,相關(guān)的非技術(shù)主題(項目估算、溝通技巧等)也會對團隊有幫助?!跷绮蜁h不是設(shè)計會議。總之,你應(yīng)專注討論那些與應(yīng)用相關(guān)的一般主題。具體的設(shè)計問題,最好是留到設(shè)計會議中去解決。7懂得丟棄“那就是你一貫的工作方法,并且是有原因的。這個方法也很好地為你所用。開始你就掌握了這個方法,很明顯它是最好的方法。真的,從那以后就不要再改變了。”敏捷的根本之一就是擁抱變化。既然變化是永恒的,你有可能一直使用相同的技術(shù)和工具嗎?不,不可能。我們一直在本章說要學(xué)習(xí)新技術(shù)和新方法。但是記住,你也需要學(xué)會如何丟棄。隨著科技進步,曾經(jīng)非常有用的東西往往會靠邊站。它們不再有用了,它們還會降低你的效率。當(dāng)Andy第一次編程的時候,內(nèi)存占用是一個大問題。你通常無法在主存儲器(大約48KB)中一次裝載整個程序,所以必須把程序切分成塊。當(dāng)一個程序塊交換進去的時候,其他一些程序塊必須出來,并且你無法在一個塊中調(diào)用另一個塊中的函數(shù)。正是這種實際約束,極大地影響了你的設(shè)計和編程技術(shù)。想想在過去,面對處理器之外的循環(huán)操作,你必須花費很大精力去手工調(diào)整匯編語言的編譯輸出??梢韵胂?,如果是使用JavaScript或者J2EE代碼,你還需要這么干嗎?對于大多數(shù)的商業(yè)應(yīng)用,技術(shù)已經(jīng)有了巨大的變化,不再像過去那樣,處處考慮內(nèi)存占用、手動的重復(fù)占位及手工調(diào)整匯編語言。\h[3]但我們?nèi)匀豢吹胶芏嚅_發(fā)者從未丟棄這些舊習(xí)慣。Andy曾經(jīng)看到過這樣一段C語言代碼:一個大的for循環(huán),循環(huán)里面的代碼一共輸出了60頁。那個作者“不相信”編譯器的優(yōu)化,所以決定自己手工實現(xiàn)循環(huán)體展開和其他一些技巧。我們只能祝愿維護那一大堆代碼的人好運。在過去,這段代碼也許可以勉強接受。但是,現(xiàn)在絕對不可以了。電腦和CPU曾經(jīng)非常昂貴,而現(xiàn)在它們就是日用品?,F(xiàn)在,開發(fā)者的時間才是緊缺和昂貴的資源。這樣的轉(zhuǎn)變在緩慢地進行著,但是人們也真正認(rèn)清了這個事實。我們看到,需要耗費10人年開發(fā)的J2EE項目已經(jīng)從輝煌走向下坡路。使用PHP,一個月的時間就可以完成,并能交付大部分的功能。像PHP這樣的語言和RubyonRails這樣的框架越來越受到關(guān)注(參見[TH05]),這表明了開發(fā)者已經(jīng)意識到舊的技術(shù)再也行不通了。但丟棄已經(jīng)會的東西并不容易。很多團隊在猶豫,是因為管理者拒絕用500美元購買一臺構(gòu)建機器(buildmachine),卻寧愿花費好幾萬美元的人工費,讓程序員花時間找出問題。而實際上,買一臺構(gòu)建機器就可以解決這些問題。如果購買機器需要花費500000美元,那樣做還情有可原,但現(xiàn)在早已時過境遷了。在學(xué)習(xí)一門新技術(shù)的時候,多問問自己,是否把太多舊的態(tài)度和方法用在了新技術(shù)上。學(xué)習(xí)面向?qū)ο缶幊毯蛯W(xué)習(xí)面向過程編程是截然不同的。很容易會發(fā)現(xiàn)有人用C語言的方式編寫Java代碼,用VB的方式編寫C#的代碼(或者用Fortran的方式做任何事情)。這樣,你辛苦地轉(zhuǎn)向一門新的語言,卻失去了期望獲得的益處。根深蒂固的習(xí)慣不可能輕易地就丟棄掉Expensivementalmodelsaren’tdiscardedlightly打破舊習(xí)慣很難,更難的是自己還沒有意識到這個問題。丟棄的第一步,就是要意識到你還在使用過時的方法,這也是最難的部分。另一個難點就是要做到真正地丟棄舊習(xí)慣。思維定式是經(jīng)過多年摸爬滾打才構(gòu)建成型的,已經(jīng)根深蒂固,沒有人可以很容易就丟棄它們。這也不是說你真地要完全丟棄它們。前面那個內(nèi)存重復(fù)占位的例子,只是在稍大緩存中用手工維護一組工件的特殊案例。盡管實現(xiàn)方式不同了,但以前的技術(shù)還在你的大腦中。你不可能撬開大腦,把這一段記憶神經(jīng)剪掉。其實,根據(jù)具體情況還可以運用舊知識。如果環(huán)境合適,可以舉一反三地靈活應(yīng)用,但一定要保證不是習(xí)慣性地落入舊習(xí)慣。應(yīng)該力求盡可能完全轉(zhuǎn)入新的開發(fā)環(huán)境。例如,學(xué)習(xí)一門新的編程語言時,應(yīng)使用推薦的集成開發(fā)環(huán)境,而不是你過去開發(fā)時用的工具插件。用這個工具編寫一個和過去完全不同類型的項目。轉(zhuǎn)換的時候,完全不要使用過去的語言開發(fā)工具。只有更少被舊習(xí)慣牽絆,才更容易養(yǎng)成新習(xí)慣。學(xué)習(xí)新的東西,丟棄舊的東西。在學(xué)習(xí)一門新技術(shù)的時候,要丟棄會阻止你前進的舊習(xí)慣。畢竟,汽車要比馬車車廂強得多。切身感受新技術(shù)會讓人感到有一點恐懼。你確實需要學(xué)習(xí)很多東西。已有的技能和習(xí)慣為你打下了很好的基礎(chǔ),但不能依賴它們。平衡的藝術(shù)□沉舟側(cè)畔千帆過,病樹前頭萬木春。要果斷丟棄舊習(xí)慣,一味遵循過時的舊習(xí)慣會危害你的職業(yè)生涯?!醪皇峭耆浥f的習(xí)慣,而是只在使用適當(dāng)?shù)募夹g(shù)時才使用它?!鯇τ谒褂玫恼Z言,要總結(jié)熟悉的語言特性,并且比較這些特性在新語言或新版本中有什么不同。8打破砂鍋問到底“接受別人給你的解釋。別人告訴你問題出在了什么地方,你就去看什么地方。不需要再浪費時間去追根究底?!鼻懊嬲劦降囊恍┝?xí)慣是關(guān)于如何提高你和團隊的技術(shù)的。下面有一個習(xí)慣幾乎總是有用,可以用于設(shè)計、調(diào)試以及理解需求。假設(shè),應(yīng)用系統(tǒng)出了大問題,他們找你來修復(fù)它。但你不熟悉這個應(yīng)用系統(tǒng),所以他們會幫助你,告訴你問題一定是出在哪個特殊的模塊中——你可以放心地忽略應(yīng)用系統(tǒng)的其他地方。你必須很快地解決這個問題,因為跟你合作的這些人耐心也很有限。當(dāng)你受到那些壓力的時候,也許會覺得受到了脅迫,不想去深入了解問題,而且別人告訴你的已經(jīng)夠深入了。然而,為了解決問題,你需要很好地了解系統(tǒng)的全局。你需要查看所有你認(rèn)為和問題相關(guān)的部分——即便其他人覺得這并不相干。觀察一下醫(yī)生是如何工作的。當(dāng)你不舒服的時候,醫(yī)生會問你各種各樣的問題——你有什么習(xí)慣,你吃了什么東西,什么地方疼痛,你已經(jīng)服過什么樣的藥等。人的身體非常復(fù)雜,會受到很多因素的影響。如果醫(yī)生沒有全面地了解狀況,就很可能出現(xiàn)誤診。例如,住在紐約市的一個病人患有高燒、皮疹、嚴(yán)重的頭痛、眼睛后面疼痛,以及肌肉和關(guān)節(jié)疼痛,他也許是染上了流感或者麻疹。但是,通過全面的檢查,醫(yī)生發(fā)現(xiàn)這個倒霉的病人剛?cè)ツ厦乐薅燃倩貋?。所以,這病也許并不是簡單的流感,還有可能是在新大陸染上的熱帶傳染病登革熱。在計算機世界中也很相似,很多問題都會影響你的應(yīng)用系統(tǒng)。為了解決問題,你需要知道許多可能的影響因素。當(dāng)找人詢問任何相關(guān)的問題時,讓他們耐心地回答你的問題,這是你的職責(zé)?;蛘撸僭O(shè)你和資深的開發(fā)者一起工作。他們可能比你更了解這個系統(tǒng)。但他們也是人,有時他們也會忘記一些東西。你的問題甚至?xí)椭麄兝砬逅悸贰D銖囊粋€新人角度提出的問題,給他們提供了一個新的視角,也許就幫助他們解決了一直令人困擾的問題?!盀槭裁础笔且粋€非常好的問題。事實上,在一本流行的管理圖書《第五項修煉》中,作者建議,在理解一個問題的時候,需要漸次地問5個以上的“為什么”。這聽起來就像退回到了4歲,那時對一切都充滿著好奇。它是很好的方式,進一步挖掘簡單直白的答案,通過這個路線,設(shè)想就會更加接近事實真相。在《第五項修煉》一書中就有這樣的例子。咨詢師訪問一個制造設(shè)備工廠的經(jīng)理,就用到了這樣一些追根究底的分析。看到地板上有油漬的時候,經(jīng)理的第一反應(yīng)是命令工人把它打掃干凈。但是,咨詢師問:“為什么地板上會有油漬?”經(jīng)理不熟悉整個流程,就會責(zé)備這是清潔隊的疏忽。咨詢師再次問道:“為什么地板上有油漬?”通過一系列漸次提出的“為什么”和許多不同部門員工的幫助,咨詢師最后找到了真正的問題所在:采購政策表述不明確,導(dǎo)致大量采購了一批有缺陷的墊圈。答案出來之后,經(jīng)理和其他員工都十分震驚,他們對這事一無所知。由此發(fā)現(xiàn)了一個重大的隱患,避免了其他方面更大的損失。而咨詢師所做的不過就是問了“為什么”?!鞍パ剑灰恐苤貑⒁淮蜗到y(tǒng),就沒有問題了?!闭娴膯??為什么呀?“你必須依次執(zhí)行3次構(gòu)建才能完成構(gòu)建?!闭娴膯??為什么呀?“我們的用戶根本不想要那個功能?!闭娴膯??為什么呀?為什么呀?不停地問為什么。不能只滿足于別人告訴你的表面現(xiàn)象。要不停地提問直到你明白問題的根源。切身感受這就好比是從礦石中采掘貴重的珠寶。你不停地篩選掉無關(guān)的物質(zhì),一次比一次深入,直到找到發(fā)光的寶石。你要能感覺到真正地理解了問題,而不是只知道表面的癥狀。平衡的藝術(shù)□你可能會跑題,問了一些與主題無關(guān)的問題。就好比是,如果汽車啟動不了,你問是不是輪胎出了問題,這是沒有任何幫助的。問“為什么”,但是要問到點子上。□當(dāng)你問“為什么”的時候,也許你會被反問:“為什么你問這個問題?”在提問之前,想好你提問的理由,這會有助于你問出恰當(dāng)?shù)膯栴}。□“這個,我不知道”是一個好的起點,應(yīng)該由此進行更進一步的調(diào)查,而不應(yīng)在此戛然結(jié)束。9把握開發(fā)節(jié)奏“我們很長時間沒有進行代碼復(fù)審,所以這周會復(fù)審所有的代碼。此外,我們也要做一個發(fā)布計劃了,那就從星期二開始,用3周時間,做下一個發(fā)布計劃?!痹谠S多不成功的項目中,基本上都是隨意安排工作計劃,沒有任何的規(guī)律。那樣的隨機安排很難處理。你根本不知道明天將會發(fā)生什么,也不知道什么時候開始下一輪的全體“消防演習(xí)”。但是,敏捷項目會有一個節(jié)奏和循環(huán),讓開發(fā)更加輕松。例如,Scrum約定了30天之內(nèi)不應(yīng)發(fā)生需求變化,這樣確保團隊有一個良性的開發(fā)節(jié)奏。這有助于防止一次計劃太多的工作和一些過大的需求變更。相反,很多敏捷實踐必須一直進行,也就是說,它貫穿于項目的整個生命周期。有人說,上帝發(fā)明了時間,就是為了防止所有事情同時發(fā)生。因此我們需要更具遠見,保持不同的開發(fā)節(jié)奏,這樣敏捷項目的所有事情就不會突然同時發(fā)生,也不會隨機發(fā)生,時間也不會不可預(yù)知。我們先來看某個工作日的情況。你希望每天工作結(jié)束的時候,都能完成自己的工作,你手上沒有遺留下任何重要的任務(wù)。當(dāng)然,每天都能這樣是不現(xiàn)實的。但是,你可以做到在每天下班離開公司前運行測試,并提交一天完成的代碼。如果已經(jīng)很晚了,并且你只是嘗試性地編寫了一些代碼,那么也許最好應(yīng)該刪掉這些代碼,第二天從頭開始。這個建議聽起來十分極端,也許確實有一點。\h[4]但是如果你正在開發(fā)小塊的任務(wù),這種方式非常有助于你管理自己的時間:如果在你工作的時候沒有一個固定的最終期限(例如一天的結(jié)束),就應(yīng)該好好想想了。它會讓你的工作有一個節(jié)奏,在每天下班的時候,提交所有的工作,開心地收工。這樣,明天就能開始新的內(nèi)容,解決下一系列難題。時間盒敏捷開發(fā)者可以從多方面得到反饋:用戶、團隊成員和測試代碼。這些反饋會幫助你駕馭項目。但是時間本身就是一個非常重要的反饋。許多的敏捷技巧來源于時間盒——設(shè)定一個短時的期限,為任務(wù)設(shè)定不能延長的最終期限。你可以選擇放棄其他方面的任務(wù),但是最終期限是不變的。你可能不知道完成所有的任務(wù)需要多少個時間盒,但每個時間盒必須是短期的、有限的,并且要完成具體的目標(biāo)。例如,迭代一般是兩周的時間。當(dāng)時間到的時候,迭代就完成了。那部分是固定不變的,但是在一個具體的迭代中完成哪些功能是靈活的。換句話說,你不會改變時間,但是你可以改變功能。相似地,你會為設(shè)計討論會設(shè)定一個時間盒,即到了指定的時間點,會議就結(jié)束,同時必須要做出最終的設(shè)計決策。當(dāng)你遇到艱難抉擇的時候,固定的時間期限會促使你做決定。你不能在討論或功能上浪費很多時間,這些時間可以用于具體的工作。時間盒會幫助你一直前進。鯊魚必須不停地向前游,否則就會死亡。在這方面,軟件項目就像是鯊魚,你需要不停地前進,同時要清楚自己的真實進度。站立會議(習(xí)慣38,第148頁)最好每天在固定的時間和地點舉行,比如說上午10點左右。要養(yǎng)成這樣的習(xí)慣,在那時就準(zhǔn)備好一切參加站立會議。最大的節(jié)拍就是迭代時間(習(xí)慣17,第69頁),一般是1~4周的時間。不管你的一個迭代是多長,都應(yīng)該堅持——確保每個迭代周期的時間相同很重要。運用有規(guī)律的開發(fā)節(jié)奏,會更容易達到目標(biāo),并確保項目不停地前進。解決任務(wù),在事情變得一團糟之前。保持事件之間穩(wěn)定重復(fù)的間隔,更容易解決常見的重復(fù)任務(wù)。切身感受項目開發(fā)需要有一致和穩(wěn)定的節(jié)奏。編輯,運行測試,代碼復(fù)審,一致的迭代,然后發(fā)布。如果知道什么時候開始下一個節(jié)拍,跳舞就會更加容易。平衡的藝術(shù)□在每天結(jié)束的時候,測試代碼,提交代碼,沒有殘留的代碼?!醪灰愕媒?jīng)常加班?!跻怨潭ā⒂幸?guī)律的長度運行迭代(第69頁,習(xí)慣17)。也許剛開始你要調(diào)整迭代的長度,找到團隊最舒服可行的時間值,但之后就必須要堅持?!跞绻_發(fā)節(jié)奏過于密集,你會精疲力竭的。一般來說,當(dāng)與其他團隊(或組織)合作時,你需要減慢開發(fā)節(jié)奏。因此人們常說,互聯(lián)網(wǎng)時代發(fā)展太快,有害健康。□有規(guī)律的開發(fā)節(jié)奏會暴露很多問題,讓你有更多鼓起勇氣的借口(第23頁,習(xí)慣4)。□就像是減肥一樣,一點點的成功也是一個很大的激勵。小而可達到的目標(biāo)會讓每個人全速前進。慶祝每一次難忘的成功:共享美食和啤酒或者團隊聚餐?!咀⑨尅縗h[1]參考MyJobWenttoIndia:52WaystoSaveYourJob[Fow05]一書。新版改名為PassionateProgrammer。\h[2]Pragmatic公司的出版人Andy和Dave曾聽不少人說,他們成立了讀書小組,討論和研究Pragmatic公司的圖書。\h[3]這些技術(shù)現(xiàn)在仍然用于嵌入式系統(tǒng)領(lǐng)域的開發(fā)。\h[4]RonJeffrey告訴我們:“我希望人們敢于經(jīng)常這么做?!钡?章交付用戶想要的軟件沒有任何計劃在遇敵后還能繼續(xù)執(zhí)行?!狧elmuthvonMoltke(德國陸軍元帥,1848—1916)客戶把需求交給你了,要你幾年后交付這個系統(tǒng)。然后,你就基于這些需求構(gòu)建客戶需要的系統(tǒng),最后按時交付??蛻艨吹搅塑浖?,連聲稱贊做得好。從此你又多了一個忠實客戶,接著你很開心地進入了下一個項目。你的項目通常都是這樣運作的,是這樣的嗎?其實,大部分人并不會遇到這樣的項目。通常情況是:客戶最后看到了軟件,要么震驚要么不高興。他們不喜歡所看到的軟件,他們認(rèn)為很多地方需要修改。他們要的功能不在他們給你的原始需求文檔中。這聽起來是不是更具代表性?HelmuthvonMoltke曾說過:“沒有任何計劃在遇敵后還能繼續(xù)執(zhí)行。”我們的敵人不是客戶,不是用戶,不是隊友,也不是管理者。真正的敵人是變化。軟件開發(fā)如戰(zhàn)爭,形勢的變

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論