Sealyu

          --- 博客已遷移至: http://www.sealyu.com/blog

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            618 隨筆 :: 87 文章 :: 225 評論 :: 0 Trackbacks

          在職業(yè)生涯的大部分時間里,我都是按照瀑布模型的方式進(jìn)行工作。不久之后,我加入了Xebia,開始以敏捷的方式做活。特別是,我們一直把遵循 Scrum和XP方法論與TDD相結(jié)合作為重點強(qiáng)調(diào)的實踐。從瀑布模型到敏捷的轉(zhuǎn)變,就像從宇宙中的一顆行星突然跨到另一顆一樣巨大。一旦完成這種轉(zhuǎn)變, 你的世界將發(fā)生翻天覆地的變化,你的思維、工作或協(xié)作方式等等,所有一切都會改變。

          我參加的隊伍由8名專業(yè)人士組成,出乎我意料的是我們中有6個之前根本沒有任何采用敏捷完成工作的經(jīng)驗。這樣,我們在其中2名有經(jīng)驗的同伴指導(dǎo)下開 始工作了。一開始,讓人高興的事情并不多,大部分的事情都讓人感到沮喪。我們認(rèn)識到,敏捷并不只是沖刺(Sprint)和沒有文檔 - 有不少細(xì)微之處你得花功夫?qū)W才行。

          這里說明一下曾經(jīng)發(fā)生過的事情:

          開始的麻煩

          1. 思維轉(zhuǎn)變

          敏捷講的全是當(dāng)下的考量、當(dāng)前的沖刺、當(dāng)前的用戶故事等。當(dāng)一路走來突然有其他某個故事出現(xiàn)在面前的時候,我們并不會事先考慮事情將如何發(fā)展。過去 在瀑布模型里,我們常常是首先考慮整個系統(tǒng),HLD(高層設(shè)計)和LLD(低層設(shè)計)是第一步,在繼續(xù)前進(jìn)之前,它們必須凍結(jié)。

          相反,敏捷的內(nèi)容完全是當(dāng)前狀態(tài)和不斷改變,要是我們的需求未來會變化,我們的設(shè)計也將隨之演變;但是我們對于超越當(dāng)前沖刺的事情并不是特別關(guān)注。要接受這一事實得花點時間。

          1. 持續(xù)換檔

          敏捷是一個不斷變化的環(huán)境。“響應(yīng)變化”是其主導(dǎo)原則之一。為了響應(yīng),開發(fā)者必須跟市面上的技術(shù)保持同步,否則它將讓你異常痛苦。

          我們曾在項目中使用了一種搜索引擎庫,但我們中只有一人對其有了解。由于這個缺陷,我們在估時、結(jié)對、站立式會議,以及其他日常實踐里都遇到了問題。

          我們面對的另一個問題是恰當(dāng)?shù)剡M(jìn)行TDD。從技術(shù)觀點看,TDD已經(jīng)有了不少選擇。你可以依賴不同的模擬和測試框架,這些往往都是你在瀑布模型里不使用的東西。要是你想采用TDD,那么就必須具備對它們的豐富知識,否則整個過程就不會太順利。

          緩慢地沖刺

          1. 測試驅(qū)動開發(fā)說的是先寫測試,然后由測試導(dǎo)出業(yè)務(wù)邏輯。這是最難適應(yīng)的事情之一,因為它完全顛覆了你的觀念。

            在瀑布模型里,總是代碼先完成,然后再進(jìn)行些測試(通常都有,但并非總是有);但TDD則完全是紅、綠和重構(gòu)。這種方法要求我們用抽象術(shù)語 進(jìn)行思考,然后由它們演變出具體的事物。由于一開始難以適應(yīng),我們往往求助于先寫出邏輯,然后確保存在覆蓋它們的測試。我把這稱為開發(fā)驅(qū)動測試(DDT) 方法。

            DDT并沒有增加太多的意義。假如你知道你的代碼將會很好地工作,那為何還要寫個測試呢?只是要證明這段代碼確實有效?應(yīng)該不止這一點。的確是這樣。例如,寫測試可以讓你的代碼在耦合性方面表現(xiàn)更好,而且還能夠為將來的代碼變更提供一個巨大的安全網(wǎng)。

          1. 在敏捷里,以抽象術(shù)語進(jìn)行思考是開發(fā)人員必須具備的技能。在敏捷中我們并不像瀑布模型那樣進(jìn)行預(yù)先設(shè)計,通過創(chuàng)建抽象和開發(fā)工作流,設(shè)計到了一定的時候自然就會現(xiàn)身。敏捷中的開發(fā)人員必須至少精通基本的設(shè)計模式,否則他們將產(chǎn)生一大堆垃圾代碼,從中只能得出拙劣的設(shè)計。

            TDD在這里對我們大有幫助。它要求我們按抽象術(shù)語進(jìn)行思考。此外,只要我們開始修改測試,我們就必須考慮進(jìn)行重構(gòu),讓我們的代碼變得更 好。DDT也能幫助我們立即識別任何質(zhì)量問題,這樣它們就能及時地得到修復(fù)。這樣,我們最終認(rèn)識到必須拋棄“首先編代碼,然后寫測試”的套路,后來我們重 新開始采用了TDD方法。

          1. 代碼質(zhì)量是團(tuán)隊的職責(zé),團(tuán)隊成員將時不時的重構(gòu)代碼或者可能會重新編寫,直到它符合預(yù)先制訂的標(biāo)準(zhǔn)。我們不要把任何情緒跟我們的代碼關(guān)聯(lián) 起來,應(yīng)該準(zhǔn)備不斷地拋棄或重寫它。遵循Venkat Subramaniam在集體所有制實踐方面的建議:“每次執(zhí)行檢入代碼操作時,我們都應(yīng)該致力于改善代碼的質(zhì)量。”
          1. 在瀑布模型里,需求是要簽字的,有點像血誓,然后你再繼續(xù)向前移動。但在敏捷里,需求與解決方案同步演變。這幫助我們在前進(jìn)的過程中讓事 情變得越來越清晰,但這也導(dǎo)致系統(tǒng)需要不時的重新設(shè)計,在最初的沖刺(1-4)里,這種情況經(jīng)常會發(fā)生。此外,Backlog也能在沖刺的中間改變,因 此,團(tuán)隊?wèi)?yīng)該根據(jù)這些變化進(jìn)行調(diào)整,因為在每個沖刺結(jié)束時交付可工作的軟件是敏捷的座右銘。
          1. 結(jié)對一開始讓人覺得是浪費時間和精力。兩人一起在同一故事上進(jìn)行工作就像是各浪費了一半的時間和精力。而且,多人完成同一故事的不同任務(wù)似乎是導(dǎo)致速度下降的原因。

            但是,敏捷中的團(tuán)隊鐘情于這種合作做事的方式,不喜歡相同項目組或房間里的人單槍匹馬地干活。當(dāng)團(tuán)隊一起工作時,他們會竭盡所能地把事情向前推進(jìn),結(jié)果你有極大的可能性是以一致的方式完成事情,而不是最終在多個戰(zhàn)線失利。

          1. 在采用TDD時,結(jié)對的效果最好。Driver和Navigator一起努力開發(fā)更好的系統(tǒng)。但如果你是按照DDT的方式進(jìn)行結(jié)對編程, 那它就不是最佳的前進(jìn)之路。在這種情況下,兩個合作者都不會知道該如何前進(jìn),例如系統(tǒng)設(shè)計應(yīng)該像什么樣子,這樣你將得到很多噪音,產(chǎn)生最終必須重寫的一堆 源代碼文件。

            遵循TDD是最佳的方式,但要是你還沒有適應(yīng)它,你仍然可以結(jié)對:利用一塊玻璃(白)板,首先畫出某個設(shè)計流程圖,然后其中一個合作者可以編寫代碼,而另一個則可以編寫測試用例。

          1. 在演示時交付可工作的軟件就像是沖刺的“石蕊測試”。但是,要是軟件不是可發(fā)布的,你會不會僅僅因為軟件可以構(gòu)建、可工作,而認(rèn)為一個沖刺就成功了呢?

            當(dāng)個別故事全部完工而某些沒有,這樣的沖刺算不算成功呢?那假如沖刺的全部故事基本完成但還有些煩人的小問題呢?

            團(tuán)隊?wèi)?yīng)該關(guān)注讓整個故事完工,所有問題得到解決,并且滿足完工標(biāo)準(zhǔn);而不是慌慌張張地盯著Backlog馬虎了事。一次實施蹩腳的沖刺沒有 任何意義,除了在繼續(xù)前進(jìn)之前必須將已完成的事情返工。時間常常是一個約束條件,因此根據(jù)故事的相對重要程度,團(tuán)隊?wèi)?yīng)該找出一種對他們提議的解決方案更具 質(zhì)量意義的實施方法。位于Backlog頂端的故事必須盡量以最好的方式開發(fā)解決,隨著我們逐漸移動到Backlog的底部,對解決方案的質(zhì)量可能會有些 妥協(xié),但并不是對完工標(biāo)準(zhǔn)而言。對于故事的實現(xiàn),更好的方式是寧缺勿濫。

          1. 站立式會議是鐵律。它們意味著成為一個共享平臺,不只是你個人的有機(jī)會告訴其他人你做過什么和接下來要做什么。人們應(yīng)該試圖去傾聽周遭發(fā)生的事情,而不只是檢查自己的檢查表看完成了哪些活動。

            莊嚴(yán)的站立式會議也必須控制在一定時間之內(nèi)。我們常常會抑制不住開始就某個問題進(jìn)行討論的誘惑,但那是必須要避免的。

          1. 敏捷團(tuán)隊相當(dāng)小,在這樣一個環(huán)境里,人們經(jīng)常會因為他們在站立式會議上的言論而被他人評判。那么,你就應(yīng)該說我們在彼此進(jìn)行腦力激蕩或者我昨天什么也沒做,再或者是我們重構(gòu)了代碼,而現(xiàn)在我搞不清楚怎么回事了之類的事情嗎?這些都只會給新人造成一種尷尬的局面。
          1. 計劃會議肯定是費腦子和讓人精疲力竭的活兒。坐在椅子里4個鐘頭確定故事點數(shù)就像是在玩輪盤賭。這些數(shù)字將決定包含在沖刺里的內(nèi)容,但是怎樣在你根本沒有經(jīng)驗的時候決定數(shù)字呢?你一定會估計錯誤。

            但這些數(shù)字注定就是可能會出錯的大致數(shù)字,這并不意味著你純粹是靠運(yùn)氣來開始玩輪盤賭。這些數(shù)字在未來的幾個沖刺之后將給予你某種指示,告訴你能夠完成的工作量。

          1. 分配故事點數(shù)是一個復(fù)雜的任務(wù),應(yīng)該按階段完成。團(tuán)隊內(nèi)部應(yīng)該首先分析故事,并與產(chǎn)品負(fù)責(zé)人進(jìn)行討論以清晰地了解需求。在得到清晰的視圖 之后,就要進(jìn)行廣泛的技術(shù)討論,考慮可以實現(xiàn)的最佳可能解決方案。這步要是完成不好,將導(dǎo)致在故事應(yīng)該如何實現(xiàn)方面模棱兩可,進(jìn)而導(dǎo)致有缺陷的估計。假 設(shè),如果某個故事接觸到了一個新的未探索領(lǐng)域,那么它應(yīng)該會相當(dāng)復(fù)雜,即便它是一個簡單的任務(wù)。即使在已知領(lǐng)域,技術(shù)解決方案的不同也會導(dǎo)致故事相當(dāng)復(fù) 雜。

            簡單干脆的故事最容易被估算,即清楚地知道需求是什么,再加上點應(yīng)該如何實現(xiàn)的細(xì)節(jié)。產(chǎn)品負(fù)責(zé)人無法提供這么干脆的故事。它們只能通過跟團(tuán)隊一起討論得出來。因此,團(tuán)隊必須花點時間來為下一個沖刺進(jìn)行調(diào)整。

          1. 回顧就像是在投票時間被賜予的演講。我們應(yīng)該已經(jīng)完成這個或那個,在下一個沖刺里我們可以完成這個或那個,但是要是這個沖刺里沒有接受某 些活兒,什么都不會發(fā)生。人們可以表達(dá)出對于不同方面的滿意與否,但是團(tuán)隊?wèi)?yīng)該著眼于從回顧的觀點里得到某些具體任務(wù),否則境況將永遠(yuǎn)保持下去。

          在扎進(jìn)敏捷之前,你可以做點準(zhǔn)備工作:

          1. 熟悉市面上的技術(shù),尤其是像JUnit、Fitnesse、EasyMock這樣的測試工具。此外,人們應(yīng)該不斷地為更好的解決方案而奮斗,因此出去找找改進(jìn)流程的新工具和新方法,尋找解決反復(fù)出現(xiàn)的問題的新框架或新設(shè)計思想和模式。
          1. Venkat Subramaniam和Andy Hunt的“高效程序員的45個習(xí)慣:敏捷開發(fā)修煉之道”是每位涉足敏捷的開發(fā)者的必讀書籍。
          1. 讀讀Robert C Martin在objectmentor.com上的“Craftsman series”和“Clean Code” 。一開始,你可以不用急著去讀它們,但在你碰到一堆麻煩的時候,你就會知道什么時候該去讀了。
          1. 在站立式會議/計劃/討論,人們評估你建議的時候中保持一顆開放的心。說出你的觀點,或者必要的時候要求幫助,你是這個項目的受益人。
          1. 測試不僅僅是為了代碼覆蓋率或質(zhì)量度量。它們還提供了某種類型的持續(xù)保持更新的文檔。人們可以先看看測試代碼,然后就知道該如何使用這段代碼了。
          1. 在項目開始就自動化構(gòu)建過程的所有事情。如果像Checkstyle這樣的小事都遺漏了,那么它的結(jié)果跟其他模型里的一樣,說得多做得少。當(dāng)你意識到這一點,求助于某種補(bǔ)救手段時,時間往往都太晚了。

          學(xué)會說A到Z,然后再讓你忘記,重新學(xué)Z到A往往不會太容易。這會帶來些痛苦,但完成轉(zhuǎn)變之后,你就會知道這樣做是值得的。

          話就說這么多,同志們,上路吧!!:)

          查看英文原文:Confessions of A New Agile Developer

          posted on 2010-11-23 16:54 seal 閱讀(270) 評論(0)  編輯  收藏 所屬分類: iPhone
          主站蜘蛛池模板: 山西省| 佛山市| 桂平市| 云阳县| 册亨县| 陕西省| 绥德县| 沾益县| 石狮市| 忻州市| 仪陇县| 天长市| 青神县| 缙云县| 荣昌县| 武定县| 徐州市| 塔河县| 龙岩市| 麻城市| 竹山县| 金川县| 电白县| 青州市| 黎川县| 汾西县| 杭锦旗| 长阳| 黄陵县| 海南省| 林甸县| 富平县| 井研县| 泰兴市| 保山市| 泾源县| 孙吴县| 赣州市| 璧山县| 绵竹市| 新平|