《代码大全2》第3章 三思而后行,前期准备
目錄
前言
本章主題
3.1 前期準(zhǔn)備的重要性
3.1.1 處于不同階段強(qiáng)調(diào)質(zhì)量
3.1.2 前期準(zhǔn)備對(duì)”構(gòu)建活動(dòng)“的影響
3.1.3 準(zhǔn)備不周全的誘因
3.1.4 我理解的準(zhǔn)備周全(純屬個(gè)人理解)
3.2 辨明你所從事的軟件的類型
3.2.1 高度迭代開(kāi)發(fā)法與序列式開(kāi)發(fā)法
?3.2.2 兩種開(kāi)發(fā)法的選擇
下個(gè)議題:如何判斷前期準(zhǔn)備工作是否到位
3.3 問(wèn)題定義的先決條件
3.4 需求的先決條件
3.4.1 為什么要有正式的需求
3.4.2 穩(wěn)定需求的神話
3.4.3 在構(gòu)建期間處理需求變更
3.4.4 核對(duì)表:需求
1. 針對(duì)功能需求
2. 針對(duì)非功能需求(質(zhì)量需求)
3. 需求的質(zhì)量
4. 需求的完備性
3.5 架構(gòu)的先決條件
3.5.1 架構(gòu)的典型組成部分
1. 程序組織
2. 主要的類
3. 數(shù)據(jù)存儲(chǔ)設(shè)計(jì)
4. 業(yè)務(wù)規(guī)則
5. 用戶界面設(shè)計(jì)
6. 資源管理
7. 安全性
8. 性能
9. 可伸縮性
10. 互用性
11. 國(guó)際化/本地化
12. 輸入/輸出
13. 錯(cuò)誤處理
14. 容錯(cuò)性
15. 架構(gòu)的可行性
16. 過(guò)度工程
17. 關(guān)于”買“還是”造“的決策
18. 關(guān)于復(fù)用的決策
19. 變更策略
20. 架構(gòu)的整體質(zhì)量
3.5.2 核對(duì)表:架構(gòu)
針對(duì)各架構(gòu)主題
架構(gòu)的總體質(zhì)量
3.6 花費(fèi)在前期準(zhǔn)備上的時(shí)間長(zhǎng)度
核對(duì)表:前期準(zhǔn)備
《Code_Complete_2》持續(xù)更新中......_@來(lái)杯咖啡的博客-CSDN博客這本書(shū)有意設(shè)計(jì)成使你既可以從頭到尾閱讀,也可以按主題閱讀。1. 如果你想從頭到尾閱讀,那么你可以直接從第2章“用隱喻來(lái)更充分地理解軟件開(kāi)發(fā)”開(kāi)始鉆研。2. 如果你想學(xué)習(xí)特定的編程技巧,那么你可以從第6章“可以工作的類”開(kāi)始,然后根據(jù)交叉引用的提示去尋找你感興趣的主題。3. 如果你不確定哪種閱讀方式更適合你,那么你可以從第3章3.2節(jié)“辦明你所從事的軟件的類型”開(kāi)始。.....................https://blog.csdn.net/qq_43783527/article/details/126275083
前言
????????木匠的諺語(yǔ)“瞄兩次,切一次”(Measure twice, cut once/三思而后行)與軟件開(kāi)發(fā)中的構(gòu)建部分有密切聯(lián)系,構(gòu)建活動(dòng)差不多占整個(gè)項(xiàng)目成本的 65%。最糟糕的軟件項(xiàng)目最終會(huì)進(jìn)行兩三次(甚至更多)構(gòu)建。將項(xiàng)目中最昂貴的部分執(zhí)行兩遍,這無(wú)論在軟件行業(yè)還是在其他行業(yè)都是愚蠢的主意。
????????就像修建建筑物一樣,項(xiàng)目的成敗很大程度上在構(gòu)建活動(dòng)開(kāi)始之前就已經(jīng)注定了。如果地基沒(méi)打好,或者計(jì)劃不充分,那么你在構(gòu)建期間能做的無(wú)非是盡量讓損害最小罷了。
本章主題
????????本章描述軟件構(gòu)建必須做的準(zhǔn)備工作。本章是為成功的軟件構(gòu)建打地基,并沒(méi)有直接討論構(gòu)建活動(dòng)。
?1、清楚的知道”準(zhǔn)備工作“有哪幾個(gè)活動(dòng)組成
準(zhǔn)備工作由下面幾個(gè)活動(dòng)組成,本章也是重點(diǎn)對(duì)以下活動(dòng)進(jìn)行敘述:
構(gòu)建活動(dòng)由下面幾個(gè)活動(dòng)組成:
2、準(zhǔn)備工作-架構(gòu)的先決條件,是我們開(kāi)發(fā)需要認(rèn)真關(guān)注的事情。
3.1 前期準(zhǔn)備的重要性
????????使用高質(zhì)量的實(shí)踐方法是那些能創(chuàng)造高質(zhì)量軟件的程序員的共性。這些高質(zhì)量的實(shí)踐方法在項(xiàng)目的初期、中期、末期都強(qiáng)調(diào)質(zhì)量。
3.1.1 處于不同階段強(qiáng)調(diào)質(zhì)量
????????如果你在項(xiàng)目的末期強(qiáng)調(diào)質(zhì)量,那么你會(huì)強(qiáng)調(diào)系統(tǒng)測(cè)試。當(dāng)提到軟件質(zhì)量保證的時(shí)候,許多人都會(huì)想到測(cè)試。但是測(cè)試只是完整的質(zhì)量保證策略的一部分,而且不是最有影響的部分。測(cè)試是不可能檢查出諸如“制造了一個(gè)錯(cuò)誤的產(chǎn)品”,或者“使用錯(cuò)誤的方法制造正確的產(chǎn)品”之類的缺陷的。這樣的缺陷必須在測(cè)試之前解決——更確切地說(shuō)是在構(gòu)建活動(dòng)之前。
????????如果你在項(xiàng)目中期強(qiáng)調(diào)質(zhì)量,那么你會(huì)強(qiáng)調(diào)構(gòu)建實(shí)踐。這些實(shí)踐是本書(shū)絕大部分篇幅的關(guān)注點(diǎn)。
????????如果你在項(xiàng)目的開(kāi)始階段強(qiáng)調(diào)質(zhì)量,那么你就會(huì)計(jì)劃、要求并且設(shè)計(jì)一個(gè)高質(zhì)量的產(chǎn)品。如果你用為 Pontiac Aztek 做的設(shè)計(jì)來(lái)開(kāi)始整個(gè)生產(chǎn)過(guò)程,那么你可以想盡辦法來(lái)測(cè)試,它也絕對(duì)不會(huì)變成勞斯萊斯。也許你能造出最好的 Aztek,但如果想要的是一輛勞斯萊斯,那么你就得從頭開(kāi)始做計(jì)劃。在軟件開(kāi)發(fā)中,你也需要在定義問(wèn)題、定下解決方案的規(guī)格,以及設(shè)計(jì)解決方案的時(shí)候做出這種計(jì)劃"。
3.1.2 前期準(zhǔn)備對(duì)”構(gòu)建活動(dòng)“的影響
????????由于構(gòu)建活動(dòng)是軟件項(xiàng)目的中間階段,在你開(kāi)始構(gòu)建的時(shí)候,項(xiàng)目前期工作己經(jīng)或多或少為這個(gè)項(xiàng)目的成功或失敗打下了基礎(chǔ)。然而,在構(gòu)建過(guò)程中,你至少應(yīng)該能辦明當(dāng)時(shí)的形勢(shì)如何,如果你看到失敗的烏云已經(jīng)出現(xiàn)在地平線上時(shí),就退回到項(xiàng)目的前期工作吧。
????????本章的其余部分將仔細(xì)講述為什么合適的準(zhǔn)備工作是非常重要的,并且告訴你如何判定“是否已經(jīng)準(zhǔn)備好開(kāi)始構(gòu)建工作了”。
3.1.3 準(zhǔn)備不周全的誘因
??????? 1、造成準(zhǔn)備工作不充分的一個(gè)常見(jiàn)原因是,那些分配去做前期準(zhǔn)備活動(dòng)的開(kāi)發(fā)人員并不具備完成這一任務(wù)的專業(yè)技能。(個(gè)人補(bǔ)充:或者說(shuō)是讓原本不是舊項(xiàng)目的開(kāi)發(fā)人員去給該舊項(xiàng)目加磚添瓦)
- 項(xiàng)目規(guī)劃、創(chuàng)作引人注目的商業(yè)案例、分析出全面而準(zhǔn)確的需求、創(chuàng)建高質(zhì)量的架構(gòu)等活動(dòng)都需要一定的技能,這些技能不是輕而易舉就能獲得的。但是絕大多數(shù)開(kāi)發(fā)人員都沒(méi)有接受過(guò)針對(duì)這些活動(dòng)的訓(xùn)練。當(dāng)開(kāi)發(fā)人員不知道如何進(jìn)行這些前期工作的時(shí)候,建議“做更多的前期工作”就完全沒(méi)有用;如果不能首先把這項(xiàng)工作做好,那么做再多也沒(méi)有意義!說(shuō)明如何進(jìn)行這些活動(dòng)已經(jīng)超出了本書(shū)的范圍,不過(guò)在本章最后的“更多資源”中,提供了許多獲取這些專業(yè)技能的途徑。
??????? 2、程序員不做準(zhǔn)備工作的最后一個(gè)原因是,管理者們對(duì)那些“花時(shí)間進(jìn)行構(gòu)建活動(dòng)的前期淮備的程序員”的冷漠已經(jīng)到了人神共憤的程度(簡(jiǎn)單理解就是:管理者們只想讓我們盡快我們寫代碼)。Barry Boehm、 GradyBooch 及 Karl Wiegers 等人25 年來(lái)一直在擂響需求和設(shè)計(jì)的戰(zhàn)鼓,因此你可以期望,管理者們應(yīng)該已經(jīng)開(kāi)始明白:軟件開(kāi)發(fā)不僅僅是寫代碼。
3.1.4 我理解的準(zhǔn)備周全(純屬個(gè)人理解)
????????我理解的準(zhǔn)備周全包含兩部分。第一部分是”產(chǎn)品文檔“足夠清晰,第二部分是”詳設(shè)“已經(jīng)確定。產(chǎn)品文檔讓我們知道了“要做什么”?當(dāng)我們確認(rèn)”可以做“的時(shí)候,詳設(shè)再來(lái)告訴我們具體”怎么做“?
3.2 辨明你所從事的軟件的類型
????????不同種類的軟件項(xiàng)目,需要在“準(zhǔn)備工作”和“構(gòu)建活動(dòng)”之間做出不同的平衡。每一個(gè)項(xiàng)目都是獨(dú)特的,但是項(xiàng)目可以歸入若干種開(kāi)發(fā)風(fēng)格。表3-2 列出了三種最常見(jiàn)的軟件項(xiàng)目種類,并且列出了各種項(xiàng)目最適合的典型實(shí)踐。
????????在真實(shí)項(xiàng)目中,你會(huì)找到表中所列這三種主調(diào)的無(wú)數(shù)種變奏。
3.2.1 高度迭代開(kāi)發(fā)法與序列式開(kāi)發(fā)法
??????? 1、開(kāi)發(fā)商業(yè)系統(tǒng)的項(xiàng)目往往受益于高度迭代的開(kāi)發(fā)法,這種方法的“計(jì)劃、需求、架構(gòu)”活動(dòng)與“構(gòu)建、系統(tǒng)測(cè)試、質(zhì)量保證”活動(dòng)交織在一起。
????????2、性命攸關(guān)的系統(tǒng)往往要求采用序列式的方法——“需求穩(wěn)定”是確保“超高等級(jí)的可靠性”的必備條件之一。?
?3.2.2 兩種開(kāi)發(fā)法的選擇
????????絕大多數(shù)的項(xiàng)目都不會(huì)完全使用序列式開(kāi)發(fā)法或者完全使用迭代式開(kāi)發(fā)法。預(yù)先詳細(xì)說(shuō)明 100%的需求和設(shè)計(jì)是不切實(shí)際的,不過(guò)對(duì)絕大多數(shù)項(xiàng)目來(lái)說(shuō),“盡早把哪些是最關(guān)鍵的需求要素和架構(gòu)要素確定下來(lái)”是很有價(jià)值的。
????????一條很有用的經(jīng)驗(yàn)規(guī)則是:
- 計(jì)劃好預(yù)先對(duì)大約 80%的需求做出詳細(xì)說(shuō)明,并給“稍后再進(jìn)行詳細(xì)說(shuō)明的額外需求”分配一定的時(shí)間。然后在項(xiàng)目進(jìn)行過(guò)程中,實(shí)施系統(tǒng)化的變更控制措施——只接受那些最有價(jià)值的新需求。
- 另一種替代方案是,預(yù)先只對(duì)最重要的20%的需求做出詳細(xì)說(shuō)明,并且計(jì)劃以小幅增量開(kāi)發(fā)軟件的剩佘部分,隨著項(xiàng)目的進(jìn)行,對(duì)額外的需求和設(shè)計(jì)做出詳細(xì)說(shuō)明。
下個(gè)議題:如何判斷前期準(zhǔn)備工作是否到位
????????既然你已經(jīng)研究過(guò)表3-2,并且確定了何種前期準(zhǔn)備適合你的項(xiàng)目,那么本章接下來(lái)將要討論的是:如何判斷每一項(xiàng)特定的前期準(zhǔn)備工作是否到位。
3.3 問(wèn)題定義的先決條件
????????在開(kāi)始構(gòu)建之前,首先要滿足的一項(xiàng)先決條件是,對(duì)這個(gè)系統(tǒng)要解決的問(wèn)題做出清楚的陳述。這有時(shí)稱為“產(chǎn)品設(shè)想/product vision ”、“設(shè)想陳述/visionstatement”、“任務(wù)陳述/mission statement” 或者“產(chǎn)品定義/product definition”。這里將它稱為“問(wèn)題定義/problem definition”。由于這本書(shū)是關(guān)于軟件構(gòu)建的,本節(jié)不打算告訴你如何去寫問(wèn)題定義,而是告訴你如何辦認(rèn)是否已經(jīng)寫好了問(wèn)題定義,以及它能否成為構(gòu)建活動(dòng)的良好基礎(chǔ)。
????????“未能定義問(wèn)題”的處罰是,你浪費(fèi)了大量時(shí)間去解決錯(cuò)誤的問(wèn)題。這是雙重處罰,因?yàn)槟?strong>也沒(méi)有解決正確的問(wèn)題。?
3.4 需求的先決條件
????????“需求”詳細(xì)描述軟件系統(tǒng)應(yīng)該做什么,這是達(dá)成解決方案的第一步。
3.4.1 為什么要有正式的需求
????????要求一套明確的需求,這點(diǎn)很重要,理由很多。
??????? 1、明確的需求有助于確保是用戶(而不是程序員)駕馭系統(tǒng)的功能。如果需求明確,那么用戶就可以自行評(píng)審,并進(jìn)行核準(zhǔn)。否則,程序員就常常會(huì)在編程期間自行決定需求。明確的需求免得你去猜測(cè)用戶想要的是什么。
??????? 2、明確的需求還有助于避免爭(zhēng)論。在開(kāi)始編程之前,先把系統(tǒng)的范圍 ((scope)確定下來(lái)。如果你和另外一個(gè)程序員對(duì)于“程序應(yīng)該做什么”意見(jiàn)不一致,你們可以查看書(shū)面的需求,以解決分岐。
??????? 3、重視需求有助于減少開(kāi)始編程開(kāi)發(fā)之后的系統(tǒng)變更情況。如果你在編碼過(guò)程中發(fā)現(xiàn)了一個(gè)代碼上的錯(cuò)誤,你只需要修改幾行的代碼,然后就能繼續(xù)工作。但是如果你在編碼的時(shí)候發(fā)現(xiàn)了一個(gè)需求錯(cuò)誤,那你就得改變?cè)O(shè)計(jì),使之符合更改后的需求。你可能需要扔掉部分舊的設(shè)計(jì),并且因?yàn)橐c已經(jīng)寫好的代碼相適應(yīng),可能導(dǎo)致新的設(shè)計(jì),與在項(xiàng)目之初進(jìn)行同樣的設(shè)計(jì)相比,花費(fèi)更長(zhǎng)的時(shí)間。此外,還需要廢棄那些受此次需求變更影響的代碼和測(cè)試用例,還需要編寫新的代碼和測(cè)試用例。即便是未受影響的代碼也需要重新測(cè)試地方的改變沒(méi)有引入任何新的錯(cuò)誤。
3.4.2 穩(wěn)定需求的神話
????????“一旦客戶接受了一份需求文檔,就再也不做更改”是一個(gè)美好的愿望。然而,對(duì)一個(gè)典型的項(xiàng)目來(lái)說(shuō),在編寫代碼之前,客戶無(wú)法可靠地描述他們想要的是什么。問(wèn)題并不在于客戶是低級(jí)生物。就如同你做這個(gè)項(xiàng)目的時(shí)間越長(zhǎng),對(duì)這個(gè)項(xiàng)目的理解也就越深入一樣,客戶參與項(xiàng)目的時(shí)間越長(zhǎng),他們對(duì)項(xiàng)目的理解也就越深入。開(kāi)發(fā)過(guò)程能夠幫助客戶更好地理解自己的需求,這是需求變更的主要來(lái)源 (Curtis,Krasner, and Iscoe 1988; Jones 1998; Wiegers 2003)。
????????典型情況下需求會(huì)有多少改動(dòng)?IBM 和其他公司的研究發(fā)現(xiàn),平均水平的項(xiàng)目在開(kāi)發(fā)過(guò)程中,需求會(huì)有25%的變化(Boehm 1981, Jones 1994, Jones 2000)。在典型的項(xiàng)目中,需求變更導(dǎo)致的返工占到返工總量的75%到85%(Leffingwell1997, Wiegers 2003)。
3.4.3 在構(gòu)建期間處理需求變更
????????在構(gòu)建期間,要最好地應(yīng)對(duì)需求變更,有以下一些可以采用的方式。
??????? 1、使用本節(jié)末尾的需求核對(duì)表來(lái)評(píng)估你的需求的質(zhì)量 。如果你的需求不夠好,那么就停止工作,退回去,先把它做好,再繼續(xù)前進(jìn)。當(dāng)然,因?yàn)樵诖似陂g你會(huì)停止編碼,所以感覺(jué)似乎進(jìn)度會(huì)落后。不過(guò),假設(shè)你正開(kāi)車從芝加哥到洛杉磯,突然看到紐約的路牌,那么停下來(lái)查看路線圖是浪費(fèi)時(shí)間嗎?當(dāng)然不是,如果沒(méi)有對(duì)準(zhǔn)正確的方向,那就要停下來(lái)檢查一下路線”。
??????? 2、確保每一個(gè)人都知道需求變更的代價(jià)。 客戶只要想到一個(gè)新功能就會(huì)很興奮。在興奮時(shí)血液會(huì)涌向大腦,人會(huì)暈頭暈?zāi)X,他會(huì)把所有你們開(kāi)過(guò)的討論需求的會(huì)議、簽字儀式。以及已經(jīng)完成的需求文檔統(tǒng)統(tǒng)拋諸腦后。最簡(jiǎn)單的對(duì)付這種新功能中毒癥患者的辦法是說(shuō):“咦,這聽(tīng)起來(lái)是一個(gè)很不錯(cuò)的主意。不過(guò)由于它不是需求文檔里的內(nèi)容,我會(huì)整理一份修訂過(guò)的進(jìn)度表和成本估計(jì)表,這樣你可以決定是現(xiàn)在實(shí)施,還是過(guò)一陣子再說(shuō)” 。“進(jìn)度”和“成本”這兩個(gè)字眼比咖啡和洗冷水澡都要提神,許多“必須要有/must haves”很快會(huì)變成“有就最好/ nice tohaves"。
??????? 3、建立一套變更控制程序。 如果你的客戶激情不減,那就要考慮建立一個(gè)正式的變更控制委員會(huì),評(píng)審提交上來(lái)的更改方案。客戶改變他們的想法,認(rèn)識(shí)到他們需要更多的功能,這不是壞事。問(wèn)題是他們提出更改方案太頻繁了,讓你跟不上進(jìn)度。如果有一套固定的變更控制程序,那么大家都會(huì)很愉快—你知道自己只需在特定時(shí)候處理變更;而客戶知道你打算處理他們的提議。
????????4、使用能適應(yīng)變更的開(kāi)發(fā)方法。 某些開(kāi)發(fā)方法讓你 “對(duì)需求變更做出響應(yīng)”的能力最大化。演進(jìn)原型(evolutionary prototyping)法能讓你在投入全部精力建造系統(tǒng)之前,先探素系統(tǒng)的需求。演進(jìn)交付(evolutionary delivery)是一種分階段交付系統(tǒng)的方法。你可以建造一小塊、從用戶獲得一點(diǎn)反饋、調(diào)整一點(diǎn)設(shè)計(jì)、做少量改動(dòng),再多建造一小塊。關(guān)鍵在于縮短開(kāi)發(fā)周期,以便更快地響應(yīng)用戶的要求。
??????? 5、放棄這個(gè)項(xiàng)目。 如果需求特別糟糕,或者極不穩(wěn)定,而上面的建議沒(méi)有一條能奏效,那就取消這個(gè)項(xiàng)目。即使你無(wú)法真的取消這個(gè)項(xiàng)目,也設(shè)想一下取消它之后會(huì)是怎樣的情況。在取消它之前想想它有可能會(huì)變得多糟糕。假如在某種情況下你可以放棄這個(gè)項(xiàng)目,那么至少也要問(wèn)問(wèn)自己,目前的情況和你所設(shè)想的那種情況有多大距離。
3.4.4 核對(duì)表:需求
????????這張需求核對(duì)表包含了一系列的問(wèn)題一一問(wèn)問(wèn)自己項(xiàng)目的需求工作做得如何。本書(shū)并不會(huì)告訴你如何做出好的需求分析,所以列表里面也不會(huì)有這樣的問(wèn)題。在開(kāi)始構(gòu)建之前,用這份列表做一次“心智健全”檢查,看看你的地基到底有多堅(jiān)固——用 “需求里氏震級(jí)”來(lái)衡量。
????????并不是核對(duì)表中所有的問(wèn)題都適用于你的項(xiàng)目。如果你做的是一個(gè)非正式項(xiàng)目,那么你會(huì)發(fā)現(xiàn)有些東西根本就不需要考慮。你還會(huì)發(fā)現(xiàn)一些問(wèn)題你需要考慮,但不需要做出正式的回答。如果你在做一個(gè)大型的、正式的項(xiàng)目,你也許就要逐條考慮了。
1. 針對(duì)功能需求
- 是否詳細(xì)定義了系統(tǒng)的全部輸入,包括其來(lái)源、精度、取值范圍、出率等?
- 是否詳細(xì)定義了系統(tǒng)的全部輸出,包括目的地、精度、取值范圍、出率、格式等?
- 是否詳細(xì)定義了所有輸出格式(Web 頁(yè)面、報(bào)表,等等)?
- 是否詳細(xì)定義了所有硬件及軟件的外部接口?
- 是否詳細(xì)定義了全部外部通信接口,包括握手協(xié)議、糾錯(cuò)協(xié)議、通信等?
- 是否列出了用戶想要做的全部事情?
- 是否詳細(xì)定義了每個(gè)任務(wù)所用的數(shù)據(jù),以及每個(gè)任務(wù)得到的數(shù)據(jù)?
2. 針對(duì)非功能需求(質(zhì)量需求)
- 是否為全部必要的操作,從用戶的視角,詳細(xì)描述了期望響應(yīng)時(shí)間?
- 是否詳細(xì)描述了其他與計(jì)時(shí)有關(guān)的考慮,例如處理時(shí)間、數(shù)據(jù)傳輸率、系統(tǒng)吞吐量?
- 是否詳細(xì)定義了安全級(jí)別?
- 是否詳細(xì)定義了可靠性,包括軟件失靈的后果、發(fā)生故障時(shí)需要保護(hù)的至關(guān)重要的信息、錯(cuò)誤檢測(cè)與恢復(fù)的策略等?
- 是否詳細(xì)定義了機(jī)器內(nèi)存和剩余磁盤空間的最小值?
- 是否詳細(xì)定義了系統(tǒng)的可維護(hù)性,包括適應(yīng)特定功能的變更、操作環(huán)境的變更、與其他軟件的接口的變更能力?
- 是否包含對(duì)“成功”的定義?“失敗”的定義呢?
3. 需求的質(zhì)量
- 需求是用用戶的語(yǔ)言書(shū)寫的嗎?用戶也這么認(rèn)為嗎?
- 每條需求都不與其他需求沖突嗎?
- 是否詳細(xì)定義了相互競(jìng)爭(zhēng)的特性之間的權(quán)衡--例如,健壯性與正確性之間的權(quán)衡?
- 是否避免在需求中規(guī)定設(shè)計(jì)(方案)?
- 需求是否在詳細(xì)程度上保持相當(dāng)一致的水平?有些需求應(yīng)該更詳細(xì)地描述嗎?有些需求應(yīng)該更粗略地描述嗎?
- 需求是否足夠清晰,即使轉(zhuǎn)交給一個(gè)獨(dú)立的小組去構(gòu)建,他們也能理解嗎?開(kāi)發(fā)者也這么想嗎?
- 每個(gè)條款都與待解決的問(wèn)題及其解決方案相關(guān)嗎?能從每個(gè)條款上溯到它在問(wèn)題域中對(duì)應(yīng)的根源嗎?
- 是否每條需求都是可測(cè)試的?是否可能進(jìn)行獨(dú)立的測(cè)試,以檢驗(yàn)滿不滿足各項(xiàng)需求?
- 是否詳細(xì)描述了所有可能的對(duì)需求的改動(dòng),包括各項(xiàng)改動(dòng)的可能性?
4. 需求的完備性
- 對(duì)于在開(kāi)始開(kāi)發(fā)之前無(wú)法獲得的信息,是否詳細(xì)描述了信息不完全的區(qū)域?
- 需求的完備度是否能達(dá)到這種程度:如果產(chǎn)品滿足所有需求,那么它就是可接受的?
- 你對(duì)全部需求都感到很舒服嗎?你是否已經(jīng)去掉了那些不可能實(shí)現(xiàn)的需求——那些只是為了安撫客戶和老板的東西?
3.5 架構(gòu)的先決條件
????????由于本書(shū)是關(guān)于軟件構(gòu)建的,因此本節(jié)不會(huì)告訴你如何開(kāi)發(fā)一個(gè)軟件的架構(gòu)。因?yàn)榧軜?gòu)比需求離構(gòu)建活動(dòng)又近了一步,所以對(duì)架構(gòu)的討論也會(huì)比對(duì)需求的討論更詳細(xì)一些。
????????好的架構(gòu)使得構(gòu)建活動(dòng)變得更容易。糟糕的架構(gòu)則使構(gòu)建活動(dòng)幾乎寸步難行。圖3-7顯示了糟糕的架構(gòu)的另一個(gè)問(wèn)題。
?????????在構(gòu)建期間或者更晚的時(shí)候進(jìn)行架構(gòu)變更,代價(jià)也是高昂的。修復(fù)軟件架構(gòu)中的錯(cuò)誤所需的時(shí)間與修復(fù)需求錯(cuò)誤所需的時(shí)間處于同一數(shù)量級(jí)——即,多于修復(fù)編碼錯(cuò)誤所需的時(shí)間(Basili and Perricone 1984, Willis 1998)。架構(gòu)變更如同需求變更一樣,看起來(lái)一個(gè)很小的改動(dòng),影響也許是非常深遠(yuǎn)的。無(wú)論為了修正錯(cuò)誤還是改進(jìn)設(shè)計(jì)而引發(fā)架構(gòu)變更,越早識(shí)別出變更越好。
3.5.1 架構(gòu)的典型組成部分
很多組成部分是優(yōu)秀的系統(tǒng)架構(gòu)所共有的。
????????如果你自己構(gòu)建整個(gè)系統(tǒng),那么在架構(gòu)工作會(huì)與更詳細(xì)的設(shè)計(jì)工作有重疊部分。在這種情況下,你至少應(yīng)該思考架構(gòu)的每個(gè)組成部分。
????????如果你目前從事的系統(tǒng)的架構(gòu)是別人做的,你應(yīng)該能夠不費(fèi)力地找出其中重要的組成部分(無(wú)須戴.上獵鹿帽、牽著獵犬、手拿放大鏡)。
????????在這兩種情況中,你都需要考慮以下的架構(gòu)組成部分。
1. 程序組織
????????系統(tǒng)架構(gòu)首先要以概括的形式對(duì)有關(guān)系統(tǒng)做一個(gè)綜述。如果沒(méi)有這種綜述,要想將成干的局部圖片(或十多個(gè)單獨(dú)的類)拼成一幅完整的圖畫(huà)是相當(dāng)傷腦筋的。如果系統(tǒng)是小小的只有12塊的智力拼圖玩具,你那一歲的小孩也能在眨眼功夫解決它。不過(guò)把12 個(gè)子系統(tǒng)拼到一起要困難一些,而且如果你不能將它們拼起來(lái),那么就無(wú)法理解你正在開(kāi)發(fā)的那個(gè)類對(duì)系統(tǒng)有何貢獻(xiàn)。
????????在架構(gòu)中,你應(yīng)該能發(fā)現(xiàn)對(duì)那些曾經(jīng)考慮過(guò)的最終組織結(jié)構(gòu)的替代方案的記敘,找到之所以選用最終的組織結(jié)構(gòu),而不用其他替代方案的理由。如果對(duì)某個(gè)類在系統(tǒng)中的角色沒(méi)有一個(gè)清晰的構(gòu)思,那么編寫這個(gè)類就是一件令人灰心喪氣的工作。描述其他組織結(jié)構(gòu),才能說(shuō)明架構(gòu)最后選定的這種系統(tǒng)組織結(jié)構(gòu)的緣由,并且表明各個(gè)類都是慎重考慮過(guò)的。有一份對(duì)設(shè)計(jì)實(shí)踐的綜述發(fā)現(xiàn),“維護(hù)‘設(shè)計(jì)的緣由’”至少與“維護(hù)設(shè)計(jì)本身”一樣重要(Rombach 1990)。
????????架構(gòu)應(yīng)該定義程序的主要構(gòu)造塊 (building blocks)。根據(jù)程序規(guī)模不同,各個(gè)構(gòu)造塊可能是單個(gè)類,也可能是由許多類組成的一個(gè)子系統(tǒng)。每個(gè)構(gòu)造塊無(wú)論是一個(gè)類還是一組協(xié)同工作的類和子程序,它們共同實(shí)現(xiàn)一種高層功能,諸如與用戶交互、顯示 web 頁(yè)面、解釋命令、封裝業(yè)務(wù)規(guī)則、訪問(wèn)數(shù)據(jù),等等。每條列在需求中的功能特性(feature)都至少應(yīng)該有一個(gè)構(gòu)造塊覆蓋它。如果兩個(gè)或多個(gè)構(gòu)造塊聲稱實(shí)現(xiàn)同一項(xiàng)功能,那么它們就應(yīng)該相互配合而不會(huì)沖突。
????????應(yīng)該明確定義各個(gè)構(gòu)造塊的責(zé)任。每個(gè)構(gòu)造塊應(yīng)該負(fù)責(zé)某一個(gè)區(qū)域的事情,并且對(duì)其他構(gòu)造塊負(fù)責(zé)的區(qū)域知道得越少越好。通過(guò)使各個(gè)構(gòu)造塊對(duì)其他構(gòu)造塊的了解達(dá)到最小,你能將設(shè)計(jì)的信息局限于各個(gè)構(gòu)造塊之內(nèi)。
2. 主要的類
關(guān)于”類的設(shè)計(jì)“可以詳細(xì)看:第6章 可以工作的類。
????????架構(gòu)應(yīng)該詳細(xì)定義所用的主要的類。它應(yīng)該指出每個(gè)主要的類的責(zé)任,以及該類如何與其他類交互。
- 它應(yīng)該包含對(duì)類的繼承體系、狀態(tài)轉(zhuǎn)換、對(duì)象持久化等的描述。如果系統(tǒng)足夠大,它應(yīng)該描述如何將這些類組織成一個(gè)個(gè)子系統(tǒng)。
- 架構(gòu)應(yīng)該記述曾經(jīng)考慮過(guò)的其他類設(shè)計(jì)方案,并給出選用當(dāng)前的組織結(jié)構(gòu)的理由。
- 架構(gòu)無(wú)須詳細(xì)說(shuō)明系統(tǒng)中的每一個(gè)類。瞄準(zhǔn) 80/20 法則:對(duì)那些構(gòu)成系統(tǒng)80%的行為的 20%的類進(jìn)行詳細(xì)說(shuō)明 (Jacobsen, Booch, and Rumbaugh 1999;Kruchten 2000)。
3. 數(shù)據(jù)存儲(chǔ)設(shè)計(jì)
????????架構(gòu)應(yīng)該描述所用到的主要文件和數(shù)據(jù)表的設(shè)計(jì)。它應(yīng)該描述曾經(jīng)考慮過(guò)的其他方案,并說(shuō)明做出選擇的理由。
- 如果應(yīng)用程序要維護(hù)一個(gè)客戶ID 的列表,而架構(gòu)師決定使用順序訪問(wèn)的列表(sequential-access list)來(lái)表示該ID 表,那么文檔就應(yīng)該解釋為什么順序訪問(wèn)的列表比隨機(jī)訪問(wèn)的列表(random-access list)、堆棧、散列表要好。
- 在構(gòu)建期間,這些信息讓你能洞察架構(gòu)師的思想。在維護(hù)階段,這種洞察力是無(wú)價(jià)之寶。離開(kāi)它,你就像看一部沒(méi)有字幕的外語(yǔ)片。
????????數(shù)據(jù)通常只應(yīng)該由一個(gè)子系統(tǒng)或 一個(gè)類直接訪問(wèn);例外的情況就是透過(guò)訪問(wèn)器類(access class)或訪問(wèn)器子程序(access routine)——以受控且抽象的方式——來(lái)訪問(wèn)數(shù)據(jù)。詳細(xì)的解釋請(qǐng)看第5.3節(jié)中的“隱藏秘密(信息隱藏)”。
????????架構(gòu)應(yīng)該詳細(xì)定義所用數(shù)據(jù)庫(kù)的高層組織結(jié)構(gòu)和內(nèi)容。
- 架構(gòu)應(yīng)該解釋為什么單個(gè)數(shù)據(jù)庫(kù)比多個(gè)數(shù)據(jù)庫(kù)要好(反之亦然),
- 解釋為什么不用平坦的文件而要用數(shù)據(jù)庫(kù),指出與其他訪問(wèn)同一數(shù)據(jù)的程序的可能交互方式,說(shuō)明會(huì)創(chuàng)建哪些數(shù)據(jù)視圖(view),等等。
4. 業(yè)務(wù)規(guī)則
????????如果架構(gòu)依賴于特定的業(yè)務(wù)規(guī)則,那么它就應(yīng)該詳細(xì)描述這些規(guī)則,并描述這些規(guī)則對(duì)系統(tǒng)設(shè)計(jì)的影響。例如,假定要求系統(tǒng)遂循這樣-條業(yè)務(wù)規(guī)則:客戶信息過(guò)時(shí)的時(shí)間不能超過(guò)30 秒。在此情況下,架構(gòu)就應(yīng)該描述這條規(guī)則對(duì)架構(gòu)采用的“保持客戶信息及時(shí)更新且同步”的方法的影響。
5. 用戶界面設(shè)計(jì)
????????用戶界面常常在需求階段進(jìn)行詳細(xì)說(shuō)明。如果沒(méi)有,就應(yīng)該在軟件架構(gòu)中進(jìn)行詳細(xì)說(shuō)明。架構(gòu)應(yīng)該詳細(xì)定義 web 頁(yè)面格式、GUI、命令行接口 (command lineinterface) 等的主要元素。用戶界面設(shè)計(jì)值得用整本書(shū)的篇幅來(lái)討論,不過(guò)這超出了本書(shū)的范圍。
6. 資源管理
????????架構(gòu)應(yīng)該描述一份管理稀缺資源的計(jì)劃。稀缺資源包括數(shù)據(jù)庫(kù)連接、線程、句柄(handle)等。在內(nèi)存受限的應(yīng)用領(lǐng)域,如驅(qū)動(dòng)程序開(kāi)發(fā)和嵌入式系統(tǒng)中,內(nèi)存管理是架構(gòu)應(yīng)該認(rèn)真對(duì)待的另一個(gè)重要領(lǐng)域。架構(gòu)應(yīng)該估算在正常情況和極端情況下的資源使用量。在簡(jiǎn)單的情況下,估算數(shù)據(jù)應(yīng)該說(shuō)明:預(yù)期的實(shí)現(xiàn)環(huán)境(運(yùn)行環(huán)境)有能力提供所需的資源。在更復(fù)雜的情況中,也許會(huì)要求應(yīng)用程序更主動(dòng)地管理其擁有的資源。如果是這樣,那么“資源管理器/resource manager” 應(yīng)和系統(tǒng)的其他部分一樣進(jìn)行認(rèn)真的架構(gòu)設(shè)計(jì)。
7. 安全性
????????架構(gòu)應(yīng)該描述實(shí)現(xiàn)設(shè)計(jì)層面和代碼層面的安全性的方法。如果先前尚未建立威脅模型(threat model),那么就應(yīng)該在架構(gòu)階段建立威脅模型。在制定編碼規(guī)范的時(shí)候應(yīng)該把安全性牢記在心,包括處理緩沖區(qū)的方法、處理非受信(untrudted)數(shù)據(jù)(用戶輸入的數(shù)據(jù)、cookies、配置數(shù)據(jù)(文件)和其他外部接口輸入的數(shù)據(jù))的規(guī)則、加密、錯(cuò)誤消息的細(xì)致程度、保護(hù)內(nèi)存中的秘密數(shù)據(jù),以及其他事項(xiàng)。
8. 性能
????????如果需要關(guān)注性能,就應(yīng)該在需求中詳細(xì)定義性能目標(biāo)。性能目標(biāo)可以包括資源的使用,這時(shí),性能目標(biāo)也應(yīng)該詳細(xì)定義資源(速度、內(nèi)存、成本)之間的優(yōu)先順序。
????????架構(gòu)應(yīng)該提供估計(jì)的數(shù)據(jù),并解釋為什么架構(gòu)師相信能達(dá)到性能目標(biāo)。如果某些部分存在達(dá)不到性能目標(biāo)的風(fēng)險(xiǎn),那么架構(gòu)也應(yīng)該指出來(lái)。如果為了滿足性能目標(biāo),需要在某些部分使用特定的算法或數(shù)據(jù)類型,架構(gòu)也應(yīng)該說(shuō)清楚。架構(gòu)中也可以包括各個(gè)類或各個(gè)對(duì)象的空間和時(shí)間預(yù)算。
9. 可伸縮性
????????可伸縮性是指系統(tǒng)增長(zhǎng)以滿足未來(lái)需求的能力。架構(gòu)應(yī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),而且可伸縮性不是問(wèn)題,那么架構(gòu)應(yīng)該明確地列出這一假設(shè)。
10. 互用性
????????如果預(yù)計(jì)這個(gè)系統(tǒng)會(huì)與其他軟件或硬件共享數(shù)據(jù)或資源,架構(gòu)應(yīng)該描述如何完成這一任務(wù)。
11. 國(guó)際化/本地化
12. 輸入/輸出
????????輸入輸出(VO)是架構(gòu)中值得注意的另一個(gè)領(lǐng)域。架構(gòu)應(yīng)該詳細(xì)定義讀取策略(reading scheme)是先做(look-ahead)、后做(look-behind)還是即時(shí)做(just-in-time)。而且應(yīng)該描述在哪一層檢測(cè) VO 錯(cuò)誤:在字段、記錄、流,或者文件的層次。
13. 錯(cuò)誤處理
????????錯(cuò)誤處理己被證實(shí)為現(xiàn)代計(jì)算機(jī)科學(xué)中最棘手的問(wèn)題之一,你不能武斷地處理它。有人估計(jì)程序中高達(dá) 90%的代碼是用來(lái)處理異常情況、進(jìn)行錯(cuò)誤處理、或做簿記(housekeeping)工作,意味著只有10%的代碼是用來(lái)處理常規(guī)的情況(Shaw inBentley 1982)。既然這么多代碼致力于處理錯(cuò)誤,那么在架構(gòu)中就應(yīng)該清楚地說(shuō)明一種“一致地處理錯(cuò)誤〞的策略。
????????錯(cuò)誤處理常被視為是“代碼約定層次/coding-convention-level” 的事情一—如果真有人注意它的話。但是因?yàn)殄e(cuò)誤處理牽連到整個(gè)系統(tǒng),因此最好在架構(gòu)層次上對(duì)待它。下面是一些需要考慮的問(wèn)題。
- 錯(cuò)誤處理是進(jìn)行糾正還是僅僅進(jìn)行檢測(cè)?如果是糾正,程序可以嘗試從錯(cuò)誤中恢復(fù)過(guò)來(lái)。如果僅僅是檢測(cè),那么程序可以像“沒(méi)有發(fā)生任何事”一樣繼續(xù)運(yùn)行,也可以退出。無(wú)論哪一種情況,都應(yīng)該通知用戶說(shuō)檢測(cè)到一個(gè)錯(cuò)誤。
- 錯(cuò)誤檢測(cè)是主動(dòng)的還是被動(dòng)的?系統(tǒng)可以主動(dòng)地預(yù)測(cè)錯(cuò)誤—例如,通過(guò)檢查用戶輸入的有效性——也可以在不能避免錯(cuò)誤的時(shí)候,被動(dòng)地響應(yīng)錯(cuò)誤——例如,當(dāng)用戶輸入的組合產(chǎn)生了一個(gè)數(shù)值溢出錯(cuò)誤時(shí)。前者可以掃清障礙,后者可以清除混亂。同樣,無(wú)論采用哪種方案,都與用戶界面有影響。
- 程序如何傳播錯(cuò)誤?程序一旦檢測(cè)到錯(cuò)誤,它可以立刻丟棄引發(fā)該錯(cuò)誤的數(shù)據(jù);也可以把這個(gè)錯(cuò)誤當(dāng)成一個(gè)錯(cuò)誤,并進(jìn)入錯(cuò)誤處理狀態(tài);或者可以等到所有處理完成,再通知用戶說(shuō)在某個(gè)地方發(fā)現(xiàn)了錯(cuò)誤。
- 錯(cuò)誤消息的處理有什么約定?如果架構(gòu)沒(méi)有詳細(xì)定義一個(gè)一致的處理策略,那用戶界面看起來(lái)就像“令人困惑的亂七八糟的抽象拼貼畫(huà)”,由程序的不同部分的各種界面拼接而成。要避免這種外觀體驗(yàn),架構(gòu)應(yīng)該建立一套有關(guān)錯(cuò)誤消息的約定。
- 如何處理異常(exceptions)? 架構(gòu)應(yīng)該規(guī)定代碼何時(shí)能夠拋出異常,在什么地方捕獲異常,如何記錄(log)這些異常,以及如何在文檔中描述異常,等等。
- 在程序中,在什么層次上處理錯(cuò)誤?你可以在發(fā)現(xiàn)錯(cuò)誤的地方處理,可以將錯(cuò)誤傳遞到專門處理錯(cuò)誤的類進(jìn)行處理,或者沿著函數(shù)調(diào)用鏈往上傳遞錯(cuò)誤。
- 每個(gè)類在驗(yàn)證其輸入數(shù)據(jù)的有效性方面需要負(fù)何種責(zé)任?是每個(gè)類負(fù)責(zé)驗(yàn)證自己的數(shù)據(jù)的有效性,還是有一組類負(fù)責(zé)驗(yàn)證整個(gè)系統(tǒng)的數(shù)據(jù)的有效性?某個(gè)層次上的類是否能假設(shè)它接收的數(shù)據(jù)是干凈的(clean,即,沒(méi)有錯(cuò)誤)?
- 你是希望用運(yùn)行環(huán)境中內(nèi)建的錯(cuò)誤處理機(jī)制,還是想建立自己的一套機(jī)制?事實(shí)上,運(yùn)行環(huán)境所擁有的某種特定的錯(cuò)誤處理方法,并不一定是符合你的需求的最佳方法。
14. 容錯(cuò)性
????????架構(gòu)還應(yīng)該詳細(xì)定義所期望的容錯(cuò)種類。容錯(cuò)是增強(qiáng)系統(tǒng)可靠性的一組技術(shù),包括檢測(cè)錯(cuò)誤;如果可能的話從錯(cuò)誤中恢復(fù);如果不能從錯(cuò)誤中恢復(fù),則包容其不利影響。
????????其他容錯(cuò)方法包括,在遇到錯(cuò)誤的時(shí)候,讓系統(tǒng)轉(zhuǎn)入某種“部分運(yùn)轉(zhuǎn)/partialoperation” 的狀態(tài),或者轉(zhuǎn)入某種“功能退化/degraded functionality” 的狀態(tài)。系統(tǒng)可以自動(dòng)關(guān)閉或重啟。這些例子經(jīng)過(guò)了必要的簡(jiǎn)化。容錯(cuò)是一個(gè)吸引人的復(fù)雜主題——可惜,它超出了本書(shū)的范圍。
15. 架構(gòu)的可行性
????????設(shè)計(jì)師多半會(huì)關(guān)注系統(tǒng)的各種能力,例如是否達(dá)到性能目標(biāo),能夠在有限的資源下運(yùn)轉(zhuǎn),實(shí)現(xiàn)環(huán)境(運(yùn)行環(huán)境)是否有足夠的支持。架構(gòu)應(yīng)該論證系統(tǒng)的技術(shù)可行性。如果在任何一個(gè)方面不可行都會(huì)導(dǎo)致項(xiàng)目無(wú)法實(shí)施,那么架構(gòu)應(yīng)該說(shuō)明“這些問(wèn)題是如何經(jīng)過(guò)研究的〞-—通過(guò)驗(yàn)證概念的原型(proof-of-conceptprototype)、研究、或其他手段。必須在全面開(kāi)展構(gòu)建之前解決掉這些風(fēng)險(xiǎn)。
16. 過(guò)度工程
????????架構(gòu)應(yīng)該清楚地指出程序員應(yīng)該“為了謹(jǐn)慎起見(jiàn)寧可進(jìn)行過(guò)度工程(overengineering)”,還是應(yīng)該做出最簡(jiǎn)單的能工作的東西。
????????詳細(xì)定義一種過(guò)度工程(裕度工程)的方法尤其重要,因?yàn)樵S多程序員會(huì)出于專業(yè)自豪感,對(duì)自己編寫的類做過(guò)度工程。通過(guò)在架構(gòu)中明確地設(shè)立期望目標(biāo),就能避免出現(xiàn)“某些類異常健壯,而其他類勉強(qiáng)夠健壯”的現(xiàn)象。
17. 關(guān)于”買“還是”造“的決策
????????最激進(jìn)的構(gòu)建軟件的解決方案是根本不去構(gòu)建它——購(gòu)買軟件,或者免費(fèi)下載開(kāi)源的軟件。
????????如果架構(gòu)不采用現(xiàn)貨供應(yīng)的組件,那么就應(yīng)該說(shuō)明“自己定制的組件應(yīng)該在哪些方面勝過(guò)現(xiàn)成的程序庫(kù)和組件”。
18. 關(guān)于復(fù)用的決策
??????? 如果開(kāi)發(fā)計(jì)劃提倡使用業(yè)已存在的軟件、測(cè)試用例、數(shù)據(jù)格式或其他原料,架構(gòu)應(yīng)該說(shuō)明:如何對(duì)復(fù)用的軟件進(jìn)行加工,使之符合其他架構(gòu)目標(biāo)——如果需要使之符合的話。
19. 變更策略
??????? 1、因?yàn)閷?duì)于程序員和用戶來(lái)說(shuō),構(gòu)建軟件產(chǎn)品都是一個(gè)學(xué)習(xí)過(guò)程,所以在開(kāi)發(fā)過(guò)程中產(chǎn)品很可能會(huì)發(fā)生變化。這些變更來(lái)自不穩(wěn)定的數(shù)據(jù)類型和文件格式、功能需求的變更、新的功能特性,等等。這些變更可能是計(jì)劃增加的新功能,也可能是沒(méi)有添加到系統(tǒng)的第一個(gè)版本中的功能。因此,軟件架構(gòu)師面臨的一個(gè)主要挑戰(zhàn)是,讓架構(gòu)足夠靈活,能夠適應(yīng)可能出現(xiàn)的變化。
交叉參考:關(guān)于有系統(tǒng)地處理變更的具體辦法,見(jiàn)第 28.2節(jié)“配置管理”。
?????? 2、 架構(gòu)應(yīng)當(dāng)清楚地描述處理變更的策略。架構(gòu)應(yīng)該列出已經(jīng)考慮過(guò)的有可能會(huì)有所增強(qiáng)的功能,并說(shuō)明“最有可能增強(qiáng)的功能同樣也是最容易實(shí)現(xiàn)的”。如果變更很可能出現(xiàn)在輸入輸出格式、用戶交互的風(fēng)格、需求的處理等方面,那么架構(gòu)就應(yīng)該說(shuō)明:這些變更已經(jīng)被預(yù)料到了,并且任何單一的變更都只會(huì)影響少數(shù)幾個(gè)類。架構(gòu)應(yīng)對(duì)變更的計(jì)劃可以很簡(jiǎn)單,比如在數(shù)據(jù)文件中放入版本號(hào)、保留一些供將來(lái)使用的字段、或者將文件設(shè)計(jì)成能夠添加新的表格。如果使用了代碼生成器,那么架構(gòu)應(yīng)該說(shuō)明,可預(yù)見(jiàn)的變更都不會(huì)超出該代碼生成器的能力范圍。
設(shè)計(jì)中的 bug 常常不易發(fā)現(xiàn);隨著演化的進(jìn)行,系統(tǒng)不斷增加新的功能特性和用途,早期的設(shè)計(jì)假設(shè)漸漸被忘記,這時(shí)設(shè)計(jì)中的bug 就會(huì)現(xiàn)身。—FerandoJ. Corbato
??????? 3、架構(gòu)應(yīng)該指出“延遲提交/delay commitment”所用的策略(延遲提交是指推遲茉些因素的確定時(shí)間,做晚綁定,以增強(qiáng)靈活性)。比如說(shuō),架構(gòu)也許規(guī)定使用表驅(qū)動(dòng)(table-driven)技術(shù)(而不使用硬編碼的if語(yǔ)句)。它也許還規(guī)定“表”中的數(shù)據(jù)是保存在外部文件中,而非直接寫在程序代碼中,這樣就能做到在不重新編譯的情況下修改程序。???
交叉引用:關(guān)于延遲提交的完整描述,見(jiàn)第5.3節(jié)中的“有意識(shí)地選擇綁定時(shí)間”?????
20. 架構(gòu)的整體質(zhì)量
3.5.2 核對(duì)表:架構(gòu)
????????以下是一份問(wèn)題列表,優(yōu)秀的架構(gòu)應(yīng)該關(guān)注這些問(wèn)題。這張核對(duì)表的意圖并非用做一份有關(guān)如何做架構(gòu)的完全指南,而是作為一種實(shí)用的評(píng)估手段,用來(lái)評(píng)估軟件食物鏈到了程序員這一頭還有多少營(yíng)養(yǎng)成分。這張核對(duì)表可用做你自己的核對(duì)表的出發(fā)點(diǎn)。就像“需求”的核對(duì)表一樣,如果你從事的是非止式項(xiàng)目,那么你會(huì)發(fā)現(xiàn)其中某些條款甚至都不用去想。如果你從事的是更大型的項(xiàng)目,那么大多數(shù)條款都會(huì)是很有用的。
針對(duì)各架構(gòu)主題
- 程序的整體組織結(jié)構(gòu)是否清晰?是否包含一個(gè)良好的架構(gòu)全局觀(及其理由)?
- 是否明確定義了主要的構(gòu)造塊(包括每個(gè)構(gòu)造塊的職責(zé)范圍及與其他構(gòu)造塊的接口)?
- 是否明顯涵蓋了“需求”中列出的所有功能(每個(gè)功能對(duì)應(yīng)的構(gòu)造塊不太多也不太少)?
- 是否描述并論證了那些最關(guān)鍵的類?
- 是否描述并論證了數(shù)據(jù)設(shè)計(jì)?
- 是否詳細(xì)定義了數(shù)據(jù)庫(kù)的組織結(jié)構(gòu)和內(nèi)容?
- 是否指出了所用關(guān)鍵的業(yè)務(wù)規(guī)則,并描述其對(duì)系統(tǒng)的影響?
- 是否描述了用戶界面設(shè)計(jì)的策略?
- 是否將用戶界面模塊化,使界面的變更不會(huì)影響程序其余部分?
- 是否描述并論證了處理 VO 的策略?
- 是否估算了稀缺資源(如線程、數(shù)據(jù)庫(kù)連接、句柄、網(wǎng)絡(luò)帶寬等)的使用量,是否描述并論證了源管理的策略?
- 是否描述了架構(gòu)的安全需求?
- 架構(gòu)是否為每個(gè)類、每個(gè)子系統(tǒng)、或每個(gè)功能域(functionality area)提出空間與時(shí)間預(yù)算?
- 架構(gòu)是否描述了如何達(dá)到可伸縮性?
- 架構(gòu)是否關(guān)注互操作性?
- 是否描述了國(guó)際化/本地化的策略?
- 是否提供了一套內(nèi)聚的錯(cuò)誤處理策略?
- 是否規(guī)定了容錯(cuò)的辦法(如果需要)?是否證實(shí)了系統(tǒng)各個(gè)部分的技術(shù)可行性?
- 是否詳細(xì)描述了過(guò)度工程(overengineering)的方法?
- 是否包含了必要的“買 vs. 造”的決策?
- 架構(gòu)是否描述了如何加工被復(fù)用的代碼,使之符合其他架構(gòu)目標(biāo)?
- 是否將架構(gòu)設(shè)計(jì)得能夠適應(yīng)很可能出現(xiàn)的變更?
架構(gòu)的總體質(zhì)量
- 架構(gòu)是否解決了全部需求?
- 有沒(méi)有哪個(gè)部分是“過(guò)度架構(gòu)/overarchitected”或“欠架構(gòu)/underarchitected'是否明確宣布了在這方面的預(yù)期指標(biāo)?
- 整個(gè)架構(gòu)是否在概念上協(xié)調(diào)一致?
- 頂層設(shè)計(jì)是否獨(dú)立于用作實(shí)現(xiàn)它的機(jī)器和語(yǔ)言?
- 是否說(shuō)明了所有主要的決策的動(dòng)機(jī)?
- 你,作為一名實(shí)現(xiàn)該系統(tǒng)的程序員,是否對(duì)這個(gè)架構(gòu)感覺(jué)良好?
3.6 花費(fèi)在前期準(zhǔn)備上的時(shí)間長(zhǎng)度
????????花費(fèi)在問(wèn)題定義、需求分析、軟件架構(gòu)上的時(shí)間,依據(jù)項(xiàng)目的需要而變化。一般說(shuō)來(lái),一個(gè)運(yùn)作良好的項(xiàng)目會(huì)在需求、架構(gòu)以及其他前期計(jì)劃方面投入10%~20%的工作量和 20%~30%的時(shí)間(McConnell 1998, Kruchten 2000)。這些數(shù)字不包括詳細(xì)設(shè)計(jì)的時(shí)間——那是構(gòu)建活動(dòng)的一部分。
????????如果需求不穩(wěn)定,同時(shí)你從事的是一個(gè)大型的正式項(xiàng)目,那你就很可能需要與需求分析師合作,以解決構(gòu)建活動(dòng)早期指出的需求問(wèn)題。你要為“與需求分析師協(xié)商〞預(yù)留一些時(shí)間,還應(yīng)預(yù)留時(shí)間給需求分析師修訂需求,這樣你才能得到一份可行的需求。
????????如果需求不穩(wěn)定,同時(shí)你從事的是一個(gè)小型的非正式的項(xiàng)目,那你很可能需要自己解決需求方面的問(wèn)題。要預(yù)留足夠的時(shí)間,將需求定義足夠清晰,讓需求的不穩(wěn)定性對(duì)構(gòu)建活動(dòng)的負(fù)面影響降至最低。
????????如果需求在任何項(xiàng)目上都不穩(wěn)定——無(wú)論正式項(xiàng)目或非正式項(xiàng)目——那就將需求分析工作視為獨(dú)立的項(xiàng)目來(lái)做。在完成需求之后,估計(jì)項(xiàng)目余下的部分要花多少時(shí)間。這是明智的辦法,因?yàn)樵谂宄龅氖鞘裁粗?#xff0c;沒(méi)人相信你能估算出合理的進(jìn)度表。這就好比你是一名承包商,有人請(qǐng)你建一棟房子。客戶問(wèn)你:“完成這項(xiàng)工作要花多少錢?”你會(huì)合理地詢問(wèn):“你想要我做什么?”客戶說(shuō):“我不能告訴你,不過(guò)我想知道需要花費(fèi)多少錢?”你該明智地感謝他浪費(fèi)了你的時(shí)間,然后轉(zhuǎn)身回家。
????????在為軟件架構(gòu)分配時(shí)間的時(shí)候,要使用與需求分析類似的方法。如果軟件是你以前沒(méi)有做過(guò)的類型,應(yīng)當(dāng)為“在新的領(lǐng)域中做設(shè)計(jì)”的不確定性預(yù)留更多時(shí)問(wèn)。你要確保創(chuàng)建良好架構(gòu)所需要的時(shí)間,不會(huì)被“為做好其他方面工作所需要的時(shí)間”所擠占。如果有必要,將架構(gòu)工作也作為獨(dú)立的項(xiàng)目來(lái)對(duì)待。
核對(duì)表:前期準(zhǔn)備
- 你是否辨明了自己所從事的軟件的類型,并對(duì)所用的開(kāi)發(fā)方法做出相應(yīng)的剪裁?
- 是否充分明確地定義了需求?而且需求足夠穩(wěn)定,能開(kāi)始構(gòu)建了?(詳見(jiàn)需求核對(duì)表。)
- 是否充分明確地定義了架構(gòu),以便開(kāi)始構(gòu)建?(詳見(jiàn)架構(gòu)核對(duì)表。)
- 是否已經(jīng)指出你的(當(dāng)前)項(xiàng)目中獨(dú)有的風(fēng)險(xiǎn)(以避免構(gòu)建活動(dòng)面臨不必更的風(fēng)險(xiǎn))?
總結(jié)
以上是生活随笔為你收集整理的《代码大全2》第3章 三思而后行,前期准备的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Arcgis For Android实现
- 下一篇: Mysql解决微信特殊符号昵称入库报错乱