文章內容源於《程式碼大全》一書,感興趣的同學可以直接閱讀書籍。
程式碼大全一書中從序到正文開始,無不提到一詞構建,那麼軟體構建到底是什麼?其實在序中已經解釋:從軟體生命週期開始,到編碼完成。
⭐程式碼構建 一般佔據了小型專案的 65%、中型專案的 50%。
⭐因此構建要為小型專案的75% 中大型專案的 50%-75% 的錯誤負責
當然,實踐也表明: 修正上述由於構建造成的錯誤付出的代價,往往比修正 由於需求和架構變更帶來的錯誤代價要小很多。
但是,這也造成了開發人員的誤導:
如果不修正這些構建造成的錯誤,往往代價是最直接的。比如一個系統錯誤或者資料維護異常,往往比 需求變更 對 軟體產品的 好壞定義來的更直接。 說白話一點,如果出現系統錯誤、或者資料維護異常,那麼軟體產品肯定不是一個好產品。但是如果 軟體產品是 可用的,只是缺乏帶給使用者更好的體驗,那麼至少是一個可用產品。
往往需求變更要付出的代價,其實在構建階段,如果採用了更好的實踐方式,那麼面對需求變更,是有更好的響應變化的能力。因此,做好構建是至關重要的。
從構建的產物看構建?
構建的產物——原始碼——也是對軟體的精確描述(勝過需求規格書和設計檔案,程式碼總是最新的,不會過期)
什麼是構建?構建的核心是什麼?
軟體開發的核心就是軟體構建,而軟體編碼則是構建的核心。軟體構建主要活動有:詳細設計、編碼、偵錯(debug)、自測(單元測試和整合測試)、整合(聯調對接)。
中文含義: 比喻的一種、不用如、像、似、好像等比喻詞彙,而是用是、為、成為、變為等詞彙來描述。把某一事物比作和他有相似關係的另一事物。例如:少年是祖國的花朵、荷葉成了一把撐開的傘。
最熟悉的隱喻應用場景?
通過把不太理解的東西和一些你較為理解的東西比較,可以對不太理解的東西產生較好的理解。這種方式就使用了隱喻、也稱之為建模。
軟體隱喻的理解程度,代表了對軟體開發的理解深度
軟體工程學中沒有標準的隱喻手段,每個人隱喻的手段不同,對軟體的理解程度則不同。大到軟體需求,小到一個方法,一行程式碼,不同的人見解是不一樣的。即軟體隱喻的理解程度、代表了對軟體開發的理解程度。這點不可否認,往往更具有經驗的開發人員,對隱喻的理解更深。
軟體隱喻為了幹什麼?
軟體隱喻並不是告訴你去哪裡尋找答案,而是告訴你該如何尋找答案。舉個例子:當你遇到一個報錯,隱喻並不是告訴你是否該去百度或者書籍中尋找答案,而是告訴你如何從報錯中,尋找解決這個報錯的答案。
⭐軟體隱喻 不是答案、不是演演算法、而是解決思路
軟體隱喻場景有哪些?
舉個例子:前段時間身份中心開發一個小需求,生成郵箱名,遇到問題是,多音字複姓的處理。由於Git開發拼音包的處理和各類開源框架的漢字拼音處理包多音字處理都有限 ,為了最大靈活度。採用了專案YML設定,存在一個小問題是:怎麼通過yml設定的K對應的Value來替換姓。有兩種解決方案:
演演算法和軟體隱喻的區別?
演演算法直接給你解決問題的指導,而隱喻告訴你該如何發現這些指導資訊,去哪裡尋找。
⭐ 演演算法像是已存在的解決方案,如果可以直接使用,那麼程式設計是最方便的。但是程式設計的難點在於問題概念化。而且程式設計的大多數錯誤都是沒有更準確的將問題概念化造成的問題。也就是說:演演算法有很多,但是為什麼不能直接使用? 對映到實際工作中: 演演算法有很多、排序啊、查詢啊、最短路徑、最大子串、迴文等等。但是實際工作中,需求並不會直接告訴你用什麼演演算法去完成什麼?而是什麼時候用什麼演演算法?將需求的核心問題概念化,在通過隱喻來使用已有的解決方案。
⭐演演算法的產生本身也是一種隱喻的手段:現實社會中已經存在的問題,或者理論,想要解決這些問題或者提出更好的理論,本身就是將某種實際問題的解決方案 隱喻成為了通用演演算法。
常用的軟體隱喻場景?
寫作 —— 編寫程式碼
將編寫程式碼 比喻為 寫作,但是實際上寫作常常要丟掉草稿。在軟體編碼中,這是代價很大的操作,最常見的就是寫到一半,發現思路不通,或者有更好的解決方案,刪掉重寫。 所以在編寫程式碼時,關鍵點是 當第一次嘗試時就讓程式碼走在正確的方向上。或者在成本最低的時候做修改。
培植耕作 ——編寫程式碼
將編寫程式碼比喻為耕作,意思是一部分一部分的開發施肥,一點點的將成果新增過軟體產品中。這樣的話開發的方式和過程不能控制。例如開發第一部分和開發第二部分,採用的開發方式和過程(比如分析、設計、實現)第一部分和第二部分之間存在關係,那麼就是不可控的,因為只有兩部分全部完成後,才能一起整合。
⭐類似瀑布模型。
養殖 —— 編寫程式碼
將編寫程式碼比喻為養殖,先搭建好框架和架構、涉及實現的細節可以建造好虛擬的類,在架構形成之後,再把真實的類一點點放進去。
⭐支援上述方法論的有演進式交付,也是敏捷開發的基礎,敏捷開發就是迭代,循序漸進的開發方法。
建造 —— 編寫程式碼
將建造房屋比喻為編寫程式碼,先要做總體設計即軟體架構設計,再出藍圖,即軟體詳細設計,最後要做建造審檢,即軟體複查(程式碼走讀)和審查(程式碼稽核)。
⭐其實很多軟體學中的術語都是從建築學中演變而來的:軟體架構(建築學)、支撐性測試(腳手架)、構建(建設),這一點體現在不少開源框架的英文官網詞語就是建築學的常用語。
⭐建築學中結構一旦出現問題,代價是毀滅性的。因此要進行規劃和建設。同理,大型商業軟體專案,往往需要做更高規的設計,來保證專案的平穩和發展。
工具箱 —— 編寫程式碼
將編寫程式碼比作工具箱,即編寫程式碼,在合適的時候採用合適工具,軟體領域中,往往不要依賴於某一種 手段或者方法,更多時候,有更多比較好的手段去解決問題。
各種隱喻的組合
隱喻是一種啟發式手段,而不是演演算法,但是隱喻沒有標準的規範,因此,適當的引申,結合經驗去隱喻。
總結:
準備工作的是目標什麼?
準備工作的目標是為了降低專案風險,讓專案平穩計劃進行。而專案前期的主要風險在於:
準備工作不足的原因是什麼?
準備工作不足的原因主要有:
開發人員並不具備前期的準備技能,例:專案規劃、創作案例、分析全面準備的需求
過早的進行編碼工作,一部分原因在於沒有經驗的開發者 有儘快開始編碼的慾望、一部分原因在於管理者對於 花時間進行前期準備的程式設計師的不支援和不理解。
⭐作者趣稱這種現象 為WISCA綜合症狀或者WIMP綜合症狀。Why Isn't Sam Coding Anything? (為什麼Sam不在寫程式碼?)Why isn't Mary Programing?(為什麼Mary沒有在程式設計?)
如何解決準備工作不足?
學習更多的技能,提升自己的水平,學會如何做好前期準備工作,如何做好需求分析
與管理者溝通,告訴他前期準備工作得重要性,優秀的管理者懂得聆聽別人的意見
商業專案的計劃、需求、架構活動與構建、系統測試、質量保證交織在一起,性命攸關的專案往往採用了更序列的方式,同時需求穩定是保證可靠穩定性的必備條件之一
⭐忽略前期準備工作的 迭代式開發,比關注前期工作的 序列式開發成本更高。
⭐成功構建的關鍵之一:理解前期準備工作的完成程度,根據此來調整開發方法。即:專案初期/需求初期,預估採用迭代式開發,5人/日工作量,當前期工作準備快完成時,對需求和專案的理解已經更加深入,這時候不能太死板,要變化著調整開發方式,和工作量的安排。
什麼時候選擇迭代式?
什麼時候選擇序列式?
為什麼需要問題定義?
在構建開始前,有一項先決條件:對這個系統要解決的問題做出清楚的陳述。
如何判斷已經寫好了問題定義?是否能成為構建活動 的良好基礎
問題定義應該站在客戶的角度,用客戶的語言來描述
⭐如果沒有好的問題定義,那麼可能解決的是一個錯誤的問題。
需求是什麼?
需求:詳細描述軟體系統該做什麼。需求活動有:需求開發,需求分析,需求定義,軟體需求,需求功能規格書。
為什麼需要需求?
明確需求,可以很大程度上減少成本。參照3-1表,需求階段沒有發現的缺陷,越往後,修復花費的成本代價越高。因此需求越穩定,那麼成本浮動就會越少。
需求的穩定性?
穩定的需求是開發的聖盃,然而實際上,專案越長,客戶對專案的理解程度會隨著參與度而增加。提出的需求隨著專案週期和一開始可能大相徑庭。IBM的研究也表明:平均每個專案會有25%的需求變更
在構建中處理需求變更?
需求核對表
軟體架構是什麼?
架構是軟體設計的高層部分,用來支撐軟體細節實現。架構也成為:系統架構,有一份獨立的架構規格書檔案描述。
架構對構建的影響?
修復架構中的缺陷所花費的成本如3-1所示,因此越穩定越詳細的架構,構建開展的越快。相反,糟糕的架構設計,構建活動會無從下手。
架構的組成部分
架構質量核對表
前期準備需要做哪些?花費時間週期?
前期準備工作包括問題定義、需求分析、架構設計。一般來說,佔總工作量的20-30%時間比較合理
前期準備工作核對表
當構建的前期準備工作已經完善,接下來需要做的就是明確構建的實現過程,即程式語言,程式設計約定,構建方法。
這部分可以參考專案型別表,做好了前期準備工作,明確了專案型別。採用何種程式語言,可以借鑑已經有名聲的經典案例。決定自己構建的語言。
變數命名、包結構、類定義、子程式名稱和定義、註釋規範、格式規約。通常能提供一個標準的程式設計手冊最好。
確定構建語言的穩定性,如果在語言最火的前期使用,那麼就需要接受語言的一定缺陷和不穩定。一門好的語言一定是受過時間的磨鍊才鍛造出來的。
通過對比構建實踐表,來確定是否有合適的構建實踐
構建實踐核對表