Measure twice, cut once.
謀定而后動(dòng)给猾。
對(duì)于軟件構(gòu)建而言,
- 前期準(zhǔn)備的意義是什么圣絮?
- 前期準(zhǔn)備的活動(dòng)有哪些草穆?
- 各個(gè)活動(dòng)的時(shí)間花費(fèi)應(yīng)如何安排灌灾?
- 相關(guān)好書推薦
意義何在?
就像修建建筑物一樣悲柱,項(xiàng)目的成敗很大程度上在構(gòu)建活動(dòng)開始之前就已經(jīng)注定了锋喜。如果地基沒打好,或者計(jì)劃不充分诗祸,那么你在構(gòu)建期間能做得無非是盡量讓損害最小罷了跑芳。
軟件構(gòu)建活動(dòng)差不多占整個(gè)項(xiàng)目成本的65%。最糟糕的軟件項(xiàng)目最終會(huì)進(jìn)行兩三次(甚至更多)構(gòu)建直颅。而良好的前期準(zhǔn)備可以很大程度降低這種風(fēng)險(xiǎn)博个。其實(shí)它的中心目標(biāo)就是降低風(fēng)險(xiǎn)。首先確保你在做正確的事情功偿,后續(xù)正確地做事(構(gòu)建)才有意義和產(chǎn)生正向價(jià)值盆佣。
訴諸邏輯
從管理角度看,做計(jì)劃意味著確定項(xiàng)目所需要用的時(shí)間械荷,人數(shù)以及計(jì)算機(jī)臺(tái)數(shù)共耍。
從技術(shù)角度看,做計(jì)劃意味著弄清楚你想要建造的是什么吨瞎,以防止浪費(fèi)錢去建造錯(cuò)誤的東西痹兜。
而且,與“先做一個(gè)錯(cuò)誤的東西出來颤诀,然后扔掉并從頭來過”的成本相比字旭,花費(fèi)比理想情況下更多的力氣对湃,找出他們真正想要的東西這種方式成本更加低廉,更值得投入遗淳。
訴諸類比
以食物鏈作為類比拍柒,如果食物鏈各層都受到了污染,那么越是食物鏈頂層的生物屈暗,最后被感染的程度就越嚴(yán)重拆讯。
訴諸數(shù)據(jù)
25年的研究數(shù)據(jù)證明,在一開始就把事情做好是最合算的养叛。
惠普种呐,IBM,休斯飛機(jī)公司一铅,TRW以及其他組織的研究人員發(fā)現(xiàn)陕贮,在建構(gòu)活動(dòng)開始之前清除一個(gè)錯(cuò)誤,那么返工的成本僅僅是在開發(fā)過程的最后階段(在系統(tǒng)測(cè)試期間或者發(fā)布之后)做同樣事情的十分之一但百分之一潘飘。
引入缺陷時(shí)間與找到缺陷時(shí)間,與修復(fù)缺陷的費(fèi)用掉缺,之間的關(guān)系卜录。(說明前期準(zhǔn)備的意義)
對(duì)自己負(fù)責(zé)
只有當(dāng)你習(xí)慣了這樣的思維,你才有能力打造高質(zhì)量的系統(tǒng)眶明,因?yàn)槲磥淼能浖到y(tǒng)是極其復(fù)雜的艰毒,沒有科學(xué)的思維和方法是沒有辦法在未來軟件行業(yè)走得更遠(yuǎn)的。
總而言之
目標(biāo)其實(shí)簡(jiǎn)單來講是圍繞以下三個(gè)子目標(biāo)開展的:
- 降低風(fēng)險(xiǎn)搜囱;
- 降低成本丑瞧;
- 提高質(zhì)量。
前期準(zhǔn)備的活動(dòng)有哪些蜀肘?
都有哪些活動(dòng)可以保證我們做到降風(fēng)險(xiǎn)绊汹,降成本以及提高質(zhì)量?讓我們先來認(rèn)識(shí)下都有哪些活動(dòng)扮宠,然后再分別介紹它們都起到什么樣的作用:
- 辨明軟件類型
- 定義問題(確定正確的靶子西乖,即方向)
- 定義需求(確定正確的靶心)
- 定義架構(gòu)(用正確方法擊中靶心,使用了正確的解決方案瞄準(zhǔn)正確的問題)
辨明軟件類型
迭代開發(fā)法對(duì)前期準(zhǔn)備的影響
通過兩個(gè)表對(duì)比坛增,我們就可以知道有無進(jìn)行前期準(zhǔn)備的成本大致消耗获雕。
由兩個(gè)表的數(shù)據(jù)(需要合理懷疑數(shù)據(jù)的準(zhǔn)確性)說明,跳過前期準(zhǔn)備收捣,使用迭代方法届案,成本將會(huì)在整個(gè)項(xiàng)目過程當(dāng)中分次支付,而不會(huì)聚集在末尾一次性支付罢艾。整個(gè)項(xiàng)目塵埃落定之后楣颠,實(shí)際的總成本是相似的尽纽,但看起來沒有那么高,因?yàn)殚_發(fā)費(fèi)用是在整個(gè)項(xiàng)目進(jìn)行過程中分期支付的球碉,而不是項(xiàng)目最后一次性結(jié)賬蜓斧,心理作用?
但有合理的前期準(zhǔn)備睁冬,無論迭代式開發(fā)法或序列式開發(fā)法挎春,都可以減少成本。(而為什么現(xiàn)在大家都選用迭代式開發(fā)法豆拨,就是為了可以持續(xù)的交付直奋,適應(yīng)市場(chǎng)競(jìng)爭(zhēng)。)
一條很有用的經(jīng)驗(yàn)規(guī)則是施禾,對(duì)于序列式開發(fā)法脚线,計(jì)劃好預(yù)先對(duì)大約80%的需求做出詳細(xì)說明,并給“稍后再進(jìn)行詳細(xì)說明的額外需求”分配一定的時(shí)間弥搞。然后在項(xiàng)目進(jìn)行過程中邮绿,實(shí)施系統(tǒng)化的變更控制措施——只接受哪些最有價(jià)值的新需求。另一種替代方案(迭代式開發(fā)法)是攀例,預(yù)先只對(duì)最重要的20%的需求做詳細(xì)說明船逮,并且計(jì)劃以小幅增量開發(fā)軟件的剩余部分,隨著項(xiàng)目的進(jìn)行粤铭,對(duì)額外的需求和設(shè)計(jì)做出詳細(xì)說明挖胃。如圖所示,說明了兩種方法活動(dòng)情況梆惯。
定義問題
對(duì)系統(tǒng)需要解決的問題作出清楚的陳述酱鸭。問題定義只涉及問題是什么,而不涉及任何可能的解決方案垛吗。
需要使用客戶的語言凹髓,而且從客戶角度來描述問題。因?yàn)樽詈玫慕鉀Q方案未必是一個(gè)計(jì)算機(jī)程序职烧。
沒有好的問題定義扁誓,你努力解決的可能是一個(gè)錯(cuò)誤的問題。
定義需求
構(gòu)建期間處理需求變更
在構(gòu)建期間遇到需求變更蚀之,可以有以下幾種方式評(píng)估和處理:
-
使用需求核對(duì)表來評(píng)估需求的質(zhì)量
- 確保每個(gè)人都知道需求變更的代價(jià)
- 建立一套變更控制程序
- 使用能適應(yīng)變更的開發(fā)方法
- 放棄這個(gè)項(xiàng)目
- 注意項(xiàng)目的商業(yè)價(jià)值
定義架構(gòu)
意義何在蝗敢?
架構(gòu)的質(zhì)量決定了系統(tǒng)的“概念完整性”。一個(gè)經(jīng)過慎重考慮的架構(gòu)為“從頂層到底層維護(hù)系統(tǒng)的概念完整性”提供了必備的結(jié)構(gòu)和體系足删,它為程序員提供了指引——其細(xì)節(jié)程度與程序員的技能和手邊的工作相配寿谴。它將工作分為幾個(gè)部分,使多個(gè)開發(fā)者或者多個(gè)開發(fā)團(tuán)隊(duì)可以獨(dú)立工作失受。
架構(gòu)的典型組成部分:
程序組織
對(duì)系統(tǒng)進(jìn)行綜述(這個(gè)綜述指什么讶泰?圖示咏瑟?文字?)痪署。你首先要了解完整的框架码泞,這樣你才能理解你正在開發(fā)的那個(gè)類對(duì)系統(tǒng)有何貢獻(xiàn)。
要了解選定當(dāng)前組織結(jié)構(gòu)的緣由狼犯。經(jīng)過與其他備選組織結(jié)構(gòu)方案的對(duì)比余寥,你可以清楚知道為什么要選定這樣一個(gè)方案,準(zhǔn)確把握它的出發(fā)點(diǎn)和完整清晰的構(gòu)思對(duì)后續(xù)的設(shè)計(jì)細(xì)化等很重要悯森。
定義程序的主要構(gòu)造塊宋舷。構(gòu)造塊負(fù)責(zé)自己區(qū)域的事,且對(duì)其他構(gòu)造塊負(fù)責(zé)的區(qū)域知道越少越好瓢姻。通過使各構(gòu)造塊對(duì)其他構(gòu)造塊的了解最小祝蝠,你能將設(shè)計(jì)的信息局限于各個(gè)構(gòu)造塊之內(nèi)。
明確定義構(gòu)造塊間的通信規(guī)則幻碱。架構(gòu)應(yīng)該描述它能直接使用哪些構(gòu)造塊绎狭,能間接使用哪些構(gòu)造塊,不能使用哪些構(gòu)造塊褥傍。
主要的類
詳細(xì)定義所用的主要的類坟岔。指出每個(gè)主要類的責(zé)任,以及該類如何與其他類交互摔桦。包含對(duì)類的繼承體系、狀態(tài)轉(zhuǎn)換承疲、對(duì)象持久化等的描述邻耕。如果系統(tǒng)足夠大,它應(yīng)該描述如何將這些類組織成一個(gè)個(gè)子系統(tǒng)燕鸽。
詳細(xì)說明構(gòu)成系統(tǒng)80%行為的20%類兄世。
數(shù)據(jù)設(shè)計(jì)
描述所用到的主要文件和數(shù)據(jù)表的設(shè)計(jì)。與曾經(jīng)考慮過的其他方案對(duì)比啊研,說明做出選擇的理由御滩。有這些理由和對(duì)比,在構(gòu)建期間党远,可以讓程序員能洞察架構(gòu)師的思想削解。在維護(hù)階段,這種洞察力是無價(jià)之寶沟娱。離開它氛驮,你就像看一部沒有字幕的外語片。
數(shù)據(jù)隱秘济似。只應(yīng)該由一個(gè)子系統(tǒng)或一個(gè)類直接訪問矫废,或其他受控且抽象的方式來訪問盏缤。
詳細(xì)定義數(shù)據(jù)庫(kù)高層組織結(jié)構(gòu)和內(nèi)容。解釋為什么使用單個(gè)(多個(gè))數(shù)據(jù)庫(kù)蓖扑。解釋為什么不用平坦的文件而用數(shù)據(jù)庫(kù)唉铜。指出與其他訪問統(tǒng)一數(shù)據(jù)的程序的可能交互方式等。
業(yè)務(wù)規(guī)則
詳細(xì)描述架構(gòu)依賴的業(yè)務(wù)規(guī)則律杠。(業(yè)務(wù)規(guī)則包含哪些潭流?例如客戶信息及時(shí)更新且同步中更新時(shí)間不得超過30s)用戶界面設(shè)計(jì)
將用戶界面模塊化。如果需求階段沒有進(jìn)行詳細(xì)說明俩功,就應(yīng)該在架構(gòu)中詳細(xì)說明幻枉。模塊化可以使我們很容易做到:砍掉交互式界面的類,插入一組命令行的類诡蜓。因?yàn)槊钚薪缑姹阌趩卧?jí)別和子系統(tǒng)級(jí)別的軟件測(cè)試熬甫。
資源管理
描述管理稀缺資源的計(jì)劃。稀缺資源包括數(shù)據(jù)庫(kù)連接蔓罚、線程椿肩、句柄等。架構(gòu)應(yīng)該估算在正常情況和極端情況下的資源使用量豺谈。
安全性
描述實(shí)現(xiàn)設(shè)計(jì)層面和代碼層面的安全性方法郑象。建立威脅模型。制定編碼規(guī)范的時(shí)候把安全性牢記在心茬末,包括處理緩沖區(qū)的方法厂榛、處理非受信數(shù)據(jù)的規(guī)則聂喇、加密宣谈、錯(cuò)誤消息的細(xì)致程度沥寥、保護(hù)內(nèi)存中的秘密數(shù)據(jù)氮唯。
性能
如果關(guān)注性能邀跃,需在需求中詳細(xì)定義性能目標(biāo)膛壹。性能目標(biāo)應(yīng)該詳細(xì)定義資源(速度稳其、內(nèi)存践瓷、成本)之間的優(yōu)先順序换衬。
架構(gòu)應(yīng)該提供估計(jì)的數(shù)據(jù)痰驱,并解釋為什么能達(dá)到性能目標(biāo)。如果某些部分存在達(dá)不到性能目標(biāo)的風(fēng)險(xiǎn)瞳浦,架構(gòu)也應(yīng)該指出來担映。如果為了滿足性能目標(biāo),需要在某些部分使用特定的算法或數(shù)據(jù)類型术幔,架構(gòu)也應(yīng)該說清楚另萤。架構(gòu)中也可以包括各個(gè)類或各個(gè)對(duì)象的空間和時(shí)間預(yù)算。可伸縮性
描述系統(tǒng)增長(zhǎng)以滿足未來需求的能力。描述系統(tǒng)如何應(yīng)對(duì)用戶數(shù)量四敞、服務(wù)器數(shù)量泛源、網(wǎng)絡(luò)節(jié)點(diǎn)數(shù)量、數(shù)據(jù)庫(kù)記錄數(shù)忿危、數(shù)據(jù)庫(kù)記錄的長(zhǎng)度达箍、交易量等的增長(zhǎng)。如果預(yù)計(jì)系統(tǒng)不會(huì)增長(zhǎng)铺厨,那么也應(yīng)該明確列出這一假設(shè)缎玫。互用性
如果預(yù)計(jì)系統(tǒng)會(huì)與其他軟件或硬件共享數(shù)據(jù)或資源,架構(gòu)應(yīng)該描述如何完成這一任務(wù)解滓。國(guó)際化/本地化
描述程序支持多個(gè)地域/文化的技術(shù)活動(dòng)赃磨,包括支持當(dāng)?shù)靥囟ǖ恼Z言,字符集等工作洼裤。架構(gòu)應(yīng)該決定邻辉,是在代碼中直接嵌入字符串;還是將這些字符串封入某個(gè)類腮鞍,并透過接口來使用它值骇;或者將這些字符串存入資源文件。并解釋選用某種方案的原因移国。輸入輸出
描述讀取策略:先做吱瘩、后做、還是即時(shí)做迹缀,而且描述在哪一層檢測(cè)I/O錯(cuò)誤:字段使碾、記錄、流祝懂,或者文件的層次部逮。錯(cuò)誤處理
架構(gòu)中應(yīng)描述一種“一致地處理錯(cuò)誤”的策略。一些需考慮的問題:容錯(cuò)性
詳細(xì)定義所期望的容錯(cuò)種類嫂易。包括錯(cuò)誤檢測(cè);如果可能從錯(cuò)誤中恢復(fù)掐禁;如果不能從錯(cuò)誤中恢復(fù)怜械,則包容其不利影響。架構(gòu)的可行性
論證系統(tǒng)的技術(shù)可行性傅事。架構(gòu)師會(huì)關(guān)注系統(tǒng)各種能力缕允,例如性能目標(biāo),能否在有限資源下運(yùn)轉(zhuǎn)蹭越,運(yùn)行環(huán)境是否有足夠的支持障本。架構(gòu)應(yīng)該說明“這些問題是如何經(jīng)過研究的”——通過驗(yàn)證概念的原型、研究、或其他手段驾霜,而且必須在全面開展構(gòu)建之前解決掉這些風(fēng)險(xiǎn)案训。過度工程
通常架構(gòu)詳細(xì)描述的系統(tǒng)會(huì)比需求詳細(xì)描述的系統(tǒng)更健壯。軟件鏈條的強(qiáng)度不是取決于最薄弱的一環(huán)粪糙,而是等于所有薄弱環(huán)節(jié)的乘積强霎。那么架構(gòu)應(yīng)該清楚指出程序員應(yīng)該“為了謹(jǐn)慎起見寧可進(jìn)行過度工程”,還是應(yīng)該做出最簡(jiǎn)單的能工作的東西蓉冈。
還應(yīng)該明確設(shè)立期望目標(biāo)城舞,避免“某些類異常健壯,而其他類勉強(qiáng)夠健壯”的現(xiàn)象寞酿。關(guān)于“買”還是“造”的決策
如果架構(gòu)不采用現(xiàn)貨供應(yīng)的組件家夺,那么就應(yīng)該說明“自己定制的組件應(yīng)該在哪些方面勝過線程的程序庫(kù)和組件”。關(guān)于復(fù)用的決策
架構(gòu)應(yīng)該說明如何對(duì)復(fù)用的軟件進(jìn)行加工伐弹,使之符合其他架構(gòu)目標(biāo)拉馋。變更策略
為應(yīng)對(duì)可能出現(xiàn)的變更,架構(gòu)應(yīng)足夠靈活掸茅,適應(yīng)可能出現(xiàn)的變化椅邓。這些變更來自不穩(wěn)定的數(shù)據(jù)類型和文件格式、功能需求的變更昧狮、新的功能特性等景馁。
架構(gòu)應(yīng)清楚描述處理變更的策略。列出可能出現(xiàn)變更的功能逗鸣。說明變更已經(jīng)被預(yù)料到了合住,并且任何單一的變更都智慧影響少數(shù)幾個(gè)類。
“延遲提交”策略撒璧。比如使用表驅(qū)動(dòng)技術(shù)透葛,也許表中的數(shù)據(jù)是保存在外部文件中,而非直接寫在代碼中卿樱,這樣就能做到不重新編譯的情況下修改程序僚害。架構(gòu)的總體質(zhì)量
大型系統(tǒng)本質(zhì)問題是維持其“概念完整性”。
一個(gè)好的架構(gòu)定義應(yīng)該要關(guān)注上述內(nèi)容繁调,并將上述內(nèi)容描述清楚萨蚕,為設(shè)計(jì)和實(shí)現(xiàn)階段鋪好一個(gè)框架。還有一個(gè)架構(gòu)核對(duì)表蹄胰,優(yōu)秀的架構(gòu)應(yīng)該關(guān)注這些問題岳遥。
前期準(zhǔn)備的時(shí)間花費(fèi)應(yīng)如何安排?
一般而言裕寨,花費(fèi)在問題定義浩蓉、需求分析派继、軟件架構(gòu)上的時(shí)間,一句項(xiàng)目的需要而變化捻艳,一個(gè)運(yùn)作良好的項(xiàng)目會(huì)在前期計(jì)劃方面投入10%20%的工作量和20%30%的時(shí)間驾窟。這不包含詳細(xì)設(shè)計(jì)的時(shí)間,因?yàn)樵敿?xì)設(shè)計(jì)是構(gòu)建活動(dòng)的一部分讯泣。
對(duì)于需求不穩(wěn)定纫普,如果是大型的正式項(xiàng)目,需要與需求分析師合作好渠,解決需求分析的問題昨稼,這樣你就需要為與需求分析師協(xié)商預(yù)留一定時(shí)間。
如果是小型非正式的項(xiàng)目拳锚,那你可能需要自己解決需求分析問題假栓,要預(yù)留時(shí)間將需求定義足夠清晰,將需求的不穩(wěn)定性對(duì)構(gòu)建活動(dòng)的負(fù)面影響降至最低霍掺。
如果軟件是你以前沒有做過的類型匾荆,應(yīng)當(dāng)為“在新的領(lǐng)域中做設(shè)計(jì)”的不確定性預(yù)留更多時(shí)間。目標(biāo)是創(chuàng)建良好的架構(gòu)杆烁,所以預(yù)估時(shí)間后牙丽,不要被“為做好其他方面工作所需要的時(shí)間”所擠占。
如果有必要兔魂,可以把需求和架構(gòu)工作當(dāng)做獨(dú)立的項(xiàng)目來對(duì)待烤芦。
相關(guān)好書推薦
需求類:
- Wiegers, Karl.《Software Requirements》 這是一本實(shí)用的、面向從業(yè)者的書籍析校,它描述了“需求”活動(dòng)的具體細(xì)節(jié)构罗,包括需求啟發(fā)、需求分析智玻、需求規(guī)格遂唧、需求驗(yàn)證、需求管理等吊奢;
- 更高階的“需求”從業(yè)人員的書:Robertson, Suzanne and James Robertson. 《Mastering the Requirements Process》盖彭。Wiegers書的很好替代品。
軟件架構(gòu)類:
- 原文版 Bass, Len, Paul Clements, and Rick Kazman. 《Software Architecture in Practice》页滚,中譯版《軟件架構(gòu)實(shí)踐》谬泌,清華大學(xué)出版社。
- Buschman, Frank, et al. 《Pattern-Oriented Architecture, Volumn 1: A System of Patterns》逻谦,中譯版《面向模式的軟件體系架構(gòu) 卷1:模式系統(tǒng)》,機(jī)械工業(yè)出版社陪蜻。
- Clements, Paul, Rick Kazman, and Mark Klein. 《Evaluating Software Architectures: Methods and Case Studies》邦马,中譯版《軟件架構(gòu)評(píng)估》,清華大學(xué)出版社。