在設計方面,作決定的時候好必須有開發者參與。但是,在一個項目中,它們不該該作全部決定,特別是業務方面的決定。程序員
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對象,編寫獨立的單元測試,而不須要馬上就集成和測試其餘系統,只有當你自信它能工做的時候,纔開始集成。
當早期就進行集成的時候,你會看到子系統之間的交互和影響,你就能夠估算它們之間通訊和共享的信息數據。相反,若是你推遲集成的時間,解決這些問題就會變得很難,須要大量和大範圍地修改代碼,會形成項目延期和一片混亂。
Checked-in code is always ready for action.
在團隊裏工做,修改一些東西的時候必須很謹慎。你要時刻經濟,沒錯改動都會影響系統的狀態和整個團隊的工做效率。下面是一個簡單的工做流程,能夠防止你提交破壞系統的代碼:
最好的辦法是你有一個持續集成系統,能夠自動集成並報告集成結果。持續集成系統就是在後臺不停地檢出、構建和測試代碼的應用。你能夠本身使用腳本快速實現這樣的方式,但若是你選擇已有的免費、開源的解決方案,它們會提供更多的功能且更加穩定。
系統能在你的機器上運行,或者能在開發者和測試人員對機器上運行,固然很好。可是它同時也須要可以部署在用戶的機器上,若是系統能運行在開發服務器上,那很好,可是它同時也要運行在生產環境中。
QA should test deployment.
這就意味着,你要能用一種可重複和可靠的方式,在目標機器上部署你的應用。若是如今你仍是手工幫助質量保證人員安裝應用,花一些時間,考慮如何將安裝過程自動化。這樣只要用戶須要,你就能夠隨時爲它們安裝系統。要提前實現它,這樣讓質量保證團隊既能夠測試應用,又能夠測試安裝過程。
有了自動化部署系統後,在項目開發的整個過程當中,會更容易適應互相依賴的變化。極可能你在安裝系統的時候,會忘記添加須要的庫或組建——在任意一臺機器上運行自動化安裝程序,你很快就會知道什麼丟失了。
從第一天起就開始交付
一開始就進行全面部署,而不是等到項目的後期,這會有不少好處。事實上,有些項目在正式開發以前,就設置好了全部的安裝環境。
在咱們公司,要求你們爲預期客戶實現一個簡單的功能演示——驗證一個概念的可行性。即便項目尚未正式開始,咱們就有了單元測試、持續集成和基於窗口的安裝程序。這樣,咱們就能夠更容易更簡單地給用戶交互這個演示系統。
在簽約以前,就能提供出如此強大的演示,這無疑證實了咱們很是專業,具備強大的開發能力。
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.
固訂價格的合同會是敏捷團隊的一大難題,咱們一直在討論如何用持續、迭代和增量的方式工做。可是如今卻有些人跑過來,想提前知道他會花費多少時間及多少成本。軟件項目,天生就是變化無常的,不可重複。若是要提早給出一個固定的價格,就幾乎確定不能遵照開發上的承諾。
根據本身的處境,選擇不一樣的戰略。
對客戶來講,這種方式的好處是項目不可能會死亡。他們能夠很早的看到工做的進度或者不足之處。他們老是能夠控制項目,能夠隨時中止項目,不須要繳納任何違約金。他們能夠控制先完成哪些功能,並能精確的知道須要花費多少資金。總而言之客戶會承擔更低的風險。