敏捷的需求分析

交付用戶想要的軟件

讓客戶作決定

在設計方面,作決定的時候好必須有開發者參與。但是,在一個項目中,它們不該該作全部決定,特別是業務方面的決定。程序員

Decide what you shouldn’t decide.
開發者(及項目經理)能作的一個最重要的決定就是:判斷哪些是本身決定不來的,應該讓企業主作決定。你不須要本身給業務上的關鍵問題作決定。畢竟那不是你的事情。若是遇到了一個問題,會影響到系統的行爲或者如何使用系統,把這個問題告訴業務負責人。若是項目領導或經理試圖全權負責這些問題,要委婉地勸說他們,這些問題最好仍是和真正的業務負責人或客戶商議。數據庫

當你和客戶討論問題的時候,準備好幾種可選擇的方案。不是從技術的角度,而是從業務的角度,介紹每種方案的優缺點,以及潛在的成本和利益。和他們討論每一個選擇對時間和預算的影響,以及如何權衡。不管他們作出了什麼決定,他們必須接受它,因此最好讓他們瞭解一切以後再作這些決定。若是時候他們又想要其餘的東西,能夠公正地就成本和時間從新談判。promise

畢竟,這是他們的決定。安全

具體技巧

  • 記錄客戶作出的決定,並註明緣由。好記性不如爛筆頭,但你選擇的記錄方法不能太笨重或太繁瑣。
  • 不要用過於具體和沒有價值的問題打擾繁忙的業務人員。若是問題對他們的業務沒有影響,就應該是沒有價值的。
  • 不要隨意假設具體的問題不會影響他們的業務。若是能影響他們的業務,就是有價值的問題。
  • 若是業務負責任回答「我不知道」,這也是一個趁心如意的答案。也許是他們尚未想到那麼遠,也許是他們只有看到運行的實物才能評估出結果。盡你所能爲他們提供建議,實現代碼的時候也要考慮可能出現的變化。

讓設計指導而不是操縱開發

「設計」是軟件開發過程不可缺乏的步驟。它幫助你理解系統的細節,理解不見和子系統之間的關係,而且指導你的實現。服務器

一些成熟的方法論很強調設計,他們但願在開始編碼以前,先有完整的設計和文檔。另外一方面,敏捷方法建議你早在開發初期就開始編碼。是否那就意味着沒有設計呢?不,絕對不是,好的設計仍然十分重要。畫關鍵工做圖是必不可少的,由於要使用類及其交互關係來描述系統是如何組織的。在作設計的時候,你須要畫時間去思考各類不一樣選擇的缺陷和益處,以及如何作權衡。架構

而後,下一步才考慮是否須要開始編碼。若是你在前期沒有考慮清楚這些問題,就草草地開始編碼,極可能會被不少意料以外的問題搞暈。可是,即便以前已經提交了設計文檔,也還會有一些意料以外的狀況出現,時刻謹記,此階段提出的設計知識基於你目前對需求的理解而已。一旦開始了編碼,一切都會改變。設計及其代碼實現會不停地發展和變化。框架

Design should be only as detailed as needed to implement.
嚴格的需求-設計-代碼-測試開發流程源於理想化的瀑布式開發方法,它致使在前面進行了過分的設計。這樣在項目的生命週期中,更新和維護這些詳細的設計文檔變成了主要工做,須要時間和資源方面的巨大投資,卻只有不多的回報。ide

若是你本身都不清楚所談論的東西,就根本不可能精確地描述它。
設計能夠分紅兩層:戰略和戰術。前期的設計屬於戰略,一般只有在沒有深刻理解需求的時候須要這樣的設計。更確切地說,它應該只描述整體戰略,不該深刻到程序方法、參數、字段和對象交互精確順序的具體細節。那應該留到戰術設計階段,它應該在項目開發的時候再具體展開。這時更適合討論如何設計類的職責。由於這仍然是一個高層次、面向目標的設計。事實上,CRC(類-職責-協做)卡片的設計方法就是用來作這個事情的。工具

如何知道一個設計上好的設計,或者正合適?代碼很天然地爲設計的好壞提供了最好的反饋。若是需求有了小的變化,它仍然容易去實現,那麼它就是好的設計。而若是小的需求變化就帶來了一大批基礎代碼的破壞,那麼設計就須要改進。單元測試

具體技巧

  • 「不要再前期作大量的設計」並非說不要設計,只是說在沒有通過真正的代碼驗證以前,不要陷入太多的設計任務。當對設計一無所知的時候,投入編碼也是一件危險的事。若是深刻編碼只是爲了學習或創造原型,只要你隨後能把這些代碼扔掉,那也是一個不錯的辦法。
  • 即便初始的設計到後面再也不管用,你仍需設計:設計行爲說無價的。「計劃說沒有價值的,但計劃的過程說必不可少的。」在設計過程當中學習說有價值的,但設計自己也許沒有太大的用處。
  • 白板、草圖、便利貼都是很是好的設計工具。複雜的建模工具只會讓你分散精力,而不是啓發你的工做。

合理地使用技術

Blindly picking a framework is the having kids to save taxes.
在考慮引入新技術或框架以前,先要把你須要解決的問題找出來。你的表述方式不一樣,會讓結果有很大差別。找到了須要解決的問題,接下來就要考慮:

  • 這個技術框架真能解決這個問題嗎?要確保它能解決你的問題,並無任何的毒反作用。若是須要,先作一個小的原型。
  • 你將會被它拴住嗎?有些技術缺少可取消性,當條件能發生變化時,這可能對項目有致命打擊。咱們要考慮它時開放技術仍是專利技術,若是是開發的技術,那又開放到什麼程度?
  • 維護成本是多少?會不會隨着時間的推移,它的維護成本會很是昂貴?畢竟,方案的花費不該該高於要解決的問題,不然就是一次失敗的投資。

具體技巧

  • 也許在項目中真正評估技術方案還爲時太早。那就好。若是你在作系統原型並要演示給客戶看,也許一個簡單的散列表就能夠代替數據庫了。若是你尚未足夠的經驗,不要急於決定用什麼技術。
  • 每一門技術都會有優勢和缺點,不管它是開源的仍是商業產品、框架、工具或者語言,必定要清楚它的利弊。
  • 不要開發那些你容易下載到的東西。雖然有時須要從最基礎開發全部你須要的東西,但那時至關危險和昂貴的。

提前集成,頻繁集成

在產品的開發過程當中,集成是一個主要的風險區域。讓你的子系統不停地增加,不去作系統集成,就等於一步一步把本身置於愈來愈大的風險中,潛在的分歧會繼續增長。相反,儘量早地集成也更容易發現風險,這樣風險及相關的代價就會至關低。而等的時間越長,你也就會越痛苦。

你能集成而且獨立
集成和獨立不是相互矛盾的,你能夠一邊進行集成,一邊進行獨立開發。
使用mock對象來隔離對象之間的依賴關係,這樣在集成以前就能夠先作測試。用一個mock對象模擬真實的對象(或者子系統)。mock對象就是真實對象的替身,它並不提供真實對象的功能,可是它更容易控制,可以模仿須要的行爲,使測試更加簡單。
你可使用mock對象,編寫獨立的單元測試,而不須要馬上就集成和測試其餘系統,只有當你自信它能工做的時候,纔開始集成。

當早期就進行集成的時候,你會看到子系統之間的交互和影響,你就能夠估算它們之間通訊和共享的信息數據。相反,若是你推遲集成的時間,解決這些問題就會變得很難,須要大量和大範圍地修改代碼,會形成項目延期和一片混亂。

具體技巧

  • 成功的集成就意味着全部的單元測試不停地經過。
  • 一般天天要和團隊成員一塊兒集成代碼好幾回,好比平均天天5~10次,甚至更多。但不要過於頻繁了。
  • 若是你集成的問題很大,那必定是集成得不夠頻繁。
  • 對那些原型和實驗代碼,也許你想要獨立開發,而不要想在集成上浪費時間。可是不能獨立開發太長時間。一旦你有了經驗,就要快速地開始集成。

保持能夠發佈

Checked-in code is always ready for action.
在團隊裏工做,修改一些東西的時候必須很謹慎。你要時刻經濟,沒錯改動都會影響系統的狀態和整個團隊的工做效率。下面是一個簡單的工做流程,能夠防止你提交破壞系統的代碼:

  • 在本地運行測試。先保證你完成的代碼能夠編譯,而且能經過全部的單元測試。接着確保系統中的其餘測試均可以經過。
  • 檢出最新的代碼。從版本控制系統中更新代碼到最新的版本,再變異和運行測試。這樣每每會發現讓你吃驚的事情:其餘人提交的代碼和你的代碼發生了衝突。
  • 提交代碼。

最好的辦法是你有一個持續集成系統,能夠自動集成並報告集成結果。持續集成系統就是在後臺不停地檢出、構建和測試代碼的應用。你能夠本身使用腳本快速實現這樣的方式,但若是你選擇已有的免費、開源的解決方案,它們會提供更多的功能且更加穩定。

具體技巧

  • 有時候,作一些大的改動後,你沒法花費太多的時間和精力去保證系統一直能夠發佈。若是總共須要一個月的時間才能保證它一週以內能夠發佈,那就算了。但這隻應該是例外,不能養成習慣。
  • 若是你不得不讓系統常去不能夠發佈,那就作一個(代碼和架構的)分支版本,你能夠繼續進行本身的實驗,若是不行,還能夠撤銷,從頭再來。千萬不能讓系統既不能夠發佈又不能夠撤銷。

提前實現自動化部署

系統能在你的機器上運行,或者能在開發者和測試人員對機器上運行,固然很好。可是它同時也須要可以部署在用戶的機器上,若是系統能運行在開發服務器上,那很好,可是它同時也要運行在生產環境中。

QA should test deployment.
這就意味着,你要能用一種可重複和可靠的方式,在目標機器上部署你的應用。若是如今你仍是手工幫助質量保證人員安裝應用,花一些時間,考慮如何將安裝過程自動化。這樣只要用戶須要,你就能夠隨時爲它們安裝系統。要提前實現它,這樣讓質量保證團隊既能夠測試應用,又能夠測試安裝過程。

有了自動化部署系統後,在項目開發的整個過程當中,會更容易適應互相依賴的變化。極可能你在安裝系統的時候,會忘記添加須要的庫或組建——在任意一臺機器上運行自動化安裝程序,你很快就會知道什麼丟失了。

從第一天起就開始交付
一開始就進行全面部署,而不是等到項目的後期,這會有不少好處。事實上,有些項目在正式開發以前,就設置好了全部的安裝環境。
在咱們公司,要求你們爲預期客戶實現一個簡單的功能演示——驗證一個概念的可行性。即便項目尚未正式開始,咱們就有了單元測試、持續集成和基於窗口的安裝程序。這樣,咱們就能夠更容易更簡單地給用戶交互這個演示系統。
在簽約以前,就能提供出如此強大的演示,這無疑證實了咱們很是專業,具備強大的開發能力。

具體技巧

  • 通常產品在安裝的時候,都須要有相應的軟硬件環境。這些環境的不一樣極可能致使不少技術支持的電話。因此檢查這些依賴關係,也是安裝過程的一部分。
  • 在沒有詢問並徵得用戶的贊成以前,安裝程序絕對不能刪除用戶的數據
  • 部署一個緊急修復的Bug應該很簡單,特別是在生產服務器的環境中。你不想在壓力之下,凌晨三點半還在手工部署系統。
  • 用戶應該能夠安全而且完整地卸載安裝程序,特別是在質量保證人員的機器環境中。
  • 若是維護安裝腳本變得很困難,那極可能是一個早起警告,預示着很高的維護成本。
  • 若是你打算把持續部署系統和產品CD或者DVD刻錄機鏈接到一塊兒,你就能夠自動地爲每一個構建制做出一個完整且有標籤的光盤。任何人想要最新的構建,只要從架子上拿最上面的一張光盤安裝便可。

使用演示得到頻繁反饋

Requirements are as fluid as ink.
沒有人的思想和觀點能夠及時凍結,特別是項目的客戶。就算算他們已經告訴你想要的東西了,他們的指望和想法仍是在不停地進化——特別是當他們在使用新系統的部分功能時,他們纔開始意識到它的影響和可能發生的問題。這就是人的本性。

此處省略了數值分析中偏微分方程的例子……

應該按期地,每隔一段時間,例如一個迭代,就與客戶會晤,而且演示已經完成的功能特性。若是你能與客戶頻繁協商,根據他們的反饋開發,每一個人均可以從中受益。客戶會清楚你的工做進度。反過來,他們也會提煉需求,而後趁熱反饋到你的團隊中。這樣,他們就會基於本身進化到指望和理解爲你導航,你編寫的程序也就愈來愈接近他們的真實需求。客戶也會基於可用的預算和時間,根據大家真實的工做進度,排列任務的優先級。

維護項目術語表(Wiki規格)
不一致的術語是致使需求誤解的一個主要緣由。企業喜歡用看似普通淺顯的詞語來表達很是具體、深入的意義。
團隊中的程序員們使用了和用戶或者業務人員不一樣的術語,最後由於「阻抗失調」致使Bug和設計錯誤。這樣的事情常常發生。
爲了不這類問題,需維護一份項目術語表。人們應該能夠公開訪問它,通常是在企業內部網或者Wiki上。
在項目開發過程當中,從術語表中爲程序結構——類、方法、模型、變量等選擇合適的名字,而且要檢查和確保這些定義一直符合用戶的指望。

跟蹤問題(工做項)
隨着項目的進展,你會獲得不少反饋——修正、建議、變動要求、功能加強、Bug修復等。要注意的信息不少,隨機的郵件和潦草的告示帖上沒法應付的。因此,要有一個跟蹤系統記錄全部這些日誌。

具體技巧

  • 當你第一次試圖用這種方法和客戶一塊兒工做的時候,也許他們被這麼多的發佈嚇到了。因此,要讓他們知道,這些都是內部的發佈(演示),時爲了他們本身的利益,不須要發佈給全面的最終用戶。
  • 一些客戶,也許會以爲沒有時間應付天天、每週甚至時每兩週的回憶。畢竟,他們還有本身的全職工做。因此要尊重客戶的時間。若是客戶只能夠接受一個月一次會議,那麼就定一個月。
  • 一些客戶的聯絡人的全職工做就是參加演示會議。他們恨不得每隔一小時就有一次演示和反饋。你會發現這麼頻繁的回憶很難應付,並且還要開發代碼讓他們看。縮減次數,只有在你作完一些東西能夠給他們演示的時候,你們才碰面。
  • 演示時用來讓客戶反饋的,有助於駕馭項目的方向。若是缺乏功能或者穩定性的時候,不該該拿來演示,那隻能讓人生氣。能夠及早說明指望的功能:讓客戶知道,他們看到的是一個正在開發中的應用,而不是一個最終已經完成的產品。

使用短迭代,增量發佈

統一過程和敏捷方法都使用迭代和增量開發。使用增量開發,可一次開發應用功能的幾個小組。每一輪的開發都是基於前一次的功能,增長爲產品增值的新功能。這時你就能夠發佈或者演示產品。

迭代開發式是,你在小且重複的週期裏完成各類開發任務:分析、設計、實現、測試和得到反饋,因此叫作迭代。

Show me a detailed long-term plan and I will show you a project that’s doomed.
對付大項目最理想的辦法就是小步前進,這也是敏捷方法的核心。大步跳躍大大的增長了風險,小步前進才能夠幫助你很好地把握平衡。

大部分用戶都但願如今就有一個夠用的軟件,而不是在一年以後,獲得一個超級的好軟件,肯定使產品可用的核心功能,而後把它們放在生產環境中,越早找到用戶的手裏越好。

詢問用戶哪些是產品可用且必不可少的核心功能,不要爲全部可能須要的華麗功能而分心,不要沉迷於你的想象而去作那些華而不實的用戶界面。有一堆的理由,值得你儘快把軟件交到用戶手中:只要交到用戶手裏,你就有了收入,這樣就有更好的理由,繼續爲產品投資了。從用戶那裏獲得的反饋會讓咱們進一步理解什麼是用戶真正想要的,以及下一步該實現哪些功能。也許你會發現一些過去認爲重要的功能,如今已經再也不重要了。

使用短迭代和增量開發可讓開發者更加專一於本身的工做,若是別人告訴你有一年的時間來完成系統,你會以爲時間很長,若是目標很遙遠,又很難讓本身去專一於他。在這個快節奏的社會,咱們都但願更快地獲得結果,但願更快的見到有形的東西。這不必定是壞事。相反,他會使一件好事,只要把它轉換成生產率和正面的反饋。

具體技巧

  • 關於迭代時間長短一直是一個很是有爭議的問題,沒有規定說迭代必需要緊挨着下一個迭代。
  • 若是每一個迭代的時間都不夠用,要麼上任務太大,要麼是迭代的時間過短,把握好本身的節奏。
  • 若是發佈的功能背離了用戶的須要,多半是由於迭代的週期太長了。用戶的須要、技術和咱們對需求的理解都會隨着時間的推移而變化,在項目發佈的時候,須要清楚地反映出這些變化。若是你發現本身工做時還帶有過期的觀點和陳腐的想法,那麼極可能你等待太長時間作調整了。
  • 增量的發佈必須是可用的,而且能爲用戶提供價值,你怎麼知道用戶會以爲有價值呢?這固然要去問用戶。

固定的價格就意味着背叛承諾

A fixed price guarantees a broken promise.
固訂價格的合同會是敏捷團隊的一大難題,咱們一直在討論如何用持續、迭代和增量的方式工做。可是如今卻有些人跑過來,想提前知道他會花費多少時間及多少成本。軟件項目,天生就是變化無常的,不可重複。若是要提早給出一個固定的價格,就幾乎確定不能遵照開發上的承諾。

根據本身的處境,選擇不一樣的戰略。

  1. 主動提議先構建系統最初的、小的和有用的部分,挑選一系列小的功能,這樣完成第一次交付差很少六到八週。向客戶解釋,這時候還不是要完成全部的功能,而是要足夠一次交付,並能讓用戶真正使用。
  2. 第一個迭代結束時,客戶有兩個選擇:能夠選擇一系列新的功能,繼續進入下一個迭代;或者能夠取消合同,僅需支付第一個迭代的幾周費用。他們要麼把如今的成果扔掉要麼找其餘的團隊來完成它。
  3. 若是他們選擇繼續前進,那麼這時候,應該就能很好地預測下一個迭代工做。在下一次迭代結束的時候,用戶仍然有一樣的選擇機會:要麼如今中止,要麼繼續下一個迭代。

對客戶來講,這種方式的好處是項目不可能會死亡。他們能夠很早的看到工做的進度或者不足之處。他們老是能夠控制項目,能夠隨時中止項目,不須要繳納任何違約金。他們能夠控制先完成哪些功能,並能精確的知道須要花費多少資金。總而言之客戶會承擔更低的風險。

具體技巧

  • 若是你對答案不滿意,那麼看看你是否能夠改變問題。
  • 若是你是在一個基於計劃的非敏捷環境中中工做,那麼要麼考慮一個基於計劃且非敏捷的開發方法,要麼換一個不一樣的環境。
  • 若是你在完成第一個迭代開發以前,拒絕作任何評估,也許你會失去這個合同,讓位於那些提供了評估的人,不管他們作了多麼不切實際的承諾。
  • 敏捷不是意味着開始編碼,咱們最終會知道什麼時候能夠完成,你仍然須要根據當前的知識和猜測,作一個大體的評估,解釋如何才能到達這個目標,並給出偏差範圍。
  • 若是你如今別無選擇,你不得不提供一個固定的價格,那麼你須要學到真正好的評估技巧。
  • 也許你會考慮在合同中肯定每一個迭代的固訂價格,但迭代的數量是能夠商量的,它能夠根據當前的工做情況進行調整。
相關文章
相關標籤/搜索