Code Complete — 編程以前

前言

《代碼大全》是本經典著做,不一樣階段,不一樣水平的人看了必然會有不一樣的感覺。像我這種新手最關注的多是代碼質量部分,而高手可能會更加關注架構。本系列博客是本身在學習時的一些記錄和感想,偏前端,或許不少內容你都瞭解了,但你必定會發現亮點。html

軟件構建

軟件開發過程當中包含了許多不一樣活動,一套專業完整的流程是這樣滴:前端

  • 定義問題程序員

  • 需求分析編程

  • 規劃架構segmentfault

  • 軟件架構或高層設計安全

  • 詳細設計架構

  • 編碼與調試框架

  • 單元測試與集成測試編程語言

  • 系統集成和測試函數

  • 保障維護

這是傳統的軟件開發模型,許多高校的畢業設計就是按這個模型來的。當時最大的感受就是文檔寫的飛起,寫代碼反而意猶未盡。事實上,這纔是真正意義上的「編程」(除去定義問題以外的其餘全部活動),寫文檔的過程其實包含了規劃和設計的工做,當詳細設計的工做完成後其實程序邏輯已經很是清晰了,這時候」編碼」就成了一種機械化的體力活。

而軟件構建,就是以編碼與調試爲核心的編程,俗曰編程。

編程(programming)和編碼(coding)的區別就比如工程師和碼農的區別。前端在接需求作開發時不少活動是在腦子裏完成的,這樣減小了時間和文檔設計成本,可是增長了編碼和維護成本。

前端編碼的工程化如今發展的愈來愈完善了,可是軟件構建的工程化貌似還不太成熟(或許跟公司和部門以及業務有關),一些部門在開發項目時大概活動是這樣滴:

  • 定義問題(產品經理提需求啦)

  • 需求分析(你們快來開會,咱們來討論下這個需求)

  • 規劃架構(這部分變成了排期,需求定好了,視覺,前端,後臺,測試,大家排下期...)

  • 軟件架構或高層設計(本身邊設計邊寫代碼去...)

  • 詳細設計(本身邊設計邊寫代碼去...)

  • 編碼與調試(寫得飛起)

  • 單元測試與集成測試(自測經過沒?經過能夠提測了)

  • 系統集成和測試(測試一邊測試一邊提bug,改完bug就能上線了)

  • 保障維護(啥?體驗很差?線上故障?趕忙保障保障...)

可見在商業公司的軟件構建流程中,最重要的軟件設計部分並無和實際編碼分開進行,而是很」敏捷」的融合在一塊兒了,這種方式各有利弊,在於取捨。

重視構建過程

提升軟件的質量和開發者的生產率很是重要——這是全部碼農的共識。

而軟件構建的質量直接影響軟件的質量和生產效率:

  • 構建活動是軟件開發的主要組成部分。構建活動在整個項目開發期中佔據了30%~80%的時間;

  • 構建活動是軟件開發中得核心活動。

  • 提升程序員的生產率。在構建活動期間,不一樣程序員的生產率差率可達10~20倍。是否是好奇爲何你老是很忙麼?好奇爲何大神的開發效率老是那麼高麼?後面會講到。

  • 構建活動的產物——源代碼,是對軟件的惟一精確描述。文檔只是參考,代碼纔是硬道理。

  • 構建活動是惟一一項確保會完成的工做。

現實狀況下軟件項目每每跳過需求和設計直接進入構建環節,以後又因爲bug太多致使時間不夠,測試環節也不那麼嚴謹。可是不管項目有多匆忙,構建活動都是不可或缺的,對構建活動進行改進,是改進軟件開發過程的有效途徑。

經過隱喻來更好的理解軟件開發

使用隱喻能夠更好的理解編程,也能很形象的向別人解釋一些晦澀的技術。

隱喻這個裝逼的詞彙其實就是一種比喻,好比計算機世界裏面所說的病毒(virus)、蠕蟲(worm)、臭蟲(bug)等等,都是隱喻。隱喻描述了軟件領域中各類特定現象和事物,藉助這些隱喻,咱們可以更深入的理解軟件開發的過程。

隱喻的重要性

重要的研發成果每每來自類比,經過把你不理解的東西和一些你比較理解又很相似的東西做比較,你能夠對這些不理解的東西產生更深入的理解。這種使用隱喻的方法也叫建模。

就好比氣體的分子運動理論是基於」撞球「模型,它把氣體分子想象成有質量且彼此發生彈性碰撞的小球,有不少有用的理論就是基於這個提出來的。

又好比光的波動理論是經過類比聲波發展起來的。並提出了」以太「的概念,但很不幸的是,此次經過類比聲波來建模的研究失敗了,由於並無找到」以太「這種東西。

從托勒密的地心說到哥白尼的日心說,花了1400年。而在這一千多年間,人民堅信不移的認爲地心說模型是對的,當一個更加合理的日心說模型出來時,全部人都以爲這是錯的。當人們相信新的理論時,都會以爲舊理論很荒謬;而當人們還在相信舊理論時,一樣會認爲新理論很荒謬。科學的發展史並非一系列從」錯誤「的隱喻到」正確「的隱喻的轉變,而是一系列」不太合適「的隱喻到」更好「的隱喻的轉變。

相對於其餘學科而言,軟件開發還很年輕,尚未一套成熟標準的隱喻。所以必然存在許多互補或互斥的隱喻。你對隱喻有多理解,也就決定了你對軟件開發有多理解。不一樣的隱喻彼此不必定排斥,應當使用對你最有益的。

我想起了一篇譯文章進程與線程的一個簡單解釋,若是你以爲文章隱喻的很是巧妙,那說明你並未深刻理解進程和線程的關係。

如何使用軟件隱喻

隱喻是一種啓發式的方法,那麼該如何使用它呢?

  • 經過它來提升你對編程問題和編程過程的洞察力

  • 幫助你思考編程過程當中得活動,想出更好的解法

相對於不善用隱喻的人,那些使用隱喻來照亮本身軟件開發過程的人,他們對於編程的理解會更好,而且可以更快的寫出好代碼。

軟件構建的前期工做

項目的成敗很大程度上在構建活動開始以前就已經註定了,若是地基沒打好,或者計劃不充分,那麼你在構建期間能作的無非是儘可能讓損害最小罷了。

前期準備的重要性

準備工做的核心目標是下降風險,要根據不一樣項目特色來選擇不一樣的下降風險的方法。準備工做不足致使的直接後果就是項目延期,項目質量低,線上風險大,上線以後又頻繁改需求。

大部分程序員都明白前期準備的重要性,可是大部分程序員都沒法抵抗」儘快開始編碼「的慾望。除了程序員,管理層也是這樣。有個很裝逼的詞彙叫作WISCA綜合症(Why Isn't Sam Coding Anything?爲何Sam不在寫代碼?),或者WIMP綜合症(Why Isn't Mary Programing?爲何Mary不在編程?),介於這兩個因素,實際項目開發時每每是準備不夠充分。

在某部門,他們作一個項目的大部分時間都花在了會議和撕逼上,也就是花在了軟件設計上;而在某某部門,項目時間大多花在編碼和測試上。到底哪一種模式好?須要數據來論證,也跟項目類型密切相關。可是單從質量上來看,確定是前者更優。

兩種模式都關注開發質量,可是一個在項目初期,一個在中/末期。若是你想開發高質量的軟件,軟件開發過程必須自始至終關注質量,在項目初期關注質量,對產品質量的正面影響比在項目末期關注質量的影響更大。

程序員的一部分工做就是教育老闆和合做者,告訴他們軟件開發過程作好準備工做的重要性。

辨明你所從事的軟件類型

不一樣類型的項目,須要在」準備工做」和「構建活動」之間找到平衡。目前經常使用的開發方式有序列式和迭代式,前者適用於需求穩定,技術熟練,風險小得項目,後者適用於設計負載,需求並未理解透徹,項目包含了諸多風險等項目。

商業軟件開發中經常使用迭代式。

問題定義

問題定義在需求分析以前,需求分析是對問題的深刻描述。若是沒有一個良好的問題定義,你努力解決的多是一個錯誤的問題。

明確需求

要有一套明確的需求,這很重要。理由不少:

  • 明確需求有助於確保是用戶(或產品經理)來駕馭系統的功能。不然程序員就會經常在編程期間自行決定需求。

  • 明確需求有利於避免爭論。

  • 重視需求有助於減小開始編程開發以後的系統變動狀況。若是在編程過程當中發現一個代碼上得錯誤,你可能只須要改幾行代碼,可是若是發現一個需求錯誤或變動,哈哈。

穩定的需求是軟件開發的聖盃。一旦需求穩定,項目就能有序平穩的進行。但實際上,IBM和其餘公司研究發現,平均水平的項目在開發過程當中,需求會有25%的變化。因此在構建期間,咱們不得不該對這種變動:

  • 創建一套變動控制程序。這個成熟的公司都會有的,好比阿里的aone。

  • 使用能適應變化的開發方法,也就是選擇合適的開發模型。

  • 注意項目的商業案例。好比有時視覺作了個很酷炫的功能,但這個功能是否是用戶真的須要的?是否能提升轉化率?仍是視覺只是想突破自我?有些需求做爲功能特點來看是不錯的想法,可是當你評估」這個需求到底增長了多大的商業價值「時就會以爲它糟透了。那些記得「考慮本身的決定所帶來的商業影響」的程序員的身價堪比黃金。

  • 確保每個人都知道需求變動的代價。這是程序員的工做之一,不少產品經理/運營或其餘需求方根本不懂技術,他們認爲很小的一個改動,應該一兩個小時就能解決的。但有時候最麻煩的多是那些懂一點點技術的需求方,他們可能接觸過,或者寫過一點demo,因此天然而然認爲這很簡單。你最好讓他們知道實際成本,不然坑的是本身。

  • 使用需求覈對表來評估你得需求質量。

若是連你本身也不知道這需求是否合理,要作多久,你能夠列個表格來覈對一下。這樣能幫你本身理清思路:

功能需求覈對

1.是否詳細定義了系統的所有輸入/輸出,包括來源、精度、取值範圍?
2.是否詳細定義了軟件/硬件的外部接口?
3.是否列出了用戶想要作的所有事情?
4.是否認義了每一個任務所用到得數據?

非功能需求覈對

1.是否爲所有必要的操做?
2.是否描述了指望響應時間,處理時間,吞吐量等指標?
3.是否詳細定義了安全級別?
4.是否認義了可靠性?錯誤檢測和恢復策略?

需求質量覈對

1.需求是用用戶的語言書寫的馬?
2.需求之間是否衝突?
3.需求是否足夠清晰?
4.需求是否均可測試?
5.是否描述了全部可能對需求的改動,包括各項改動的可能性?

需求的完備性

1.對於開發前沒法得到的信息,是否詳細描述?
2.你對所有需求都感到舒服嗎?你是否已經去掉了那些不可能實現的需求?或者說並無什麼卵用的需求?

上面這個表格只是列出了一些點,不一樣項目的核對點確定不一樣,可是能夠參考,幫助你本身理清需求思路很是重要,當需求來臨以後,咱們不僅是考慮到何時可以上,還應考慮上述因素以及所以而帶來的成本。

天啦擼,看到這裏已經感同身受了。

架構的先決條件

架構的質量決定了系統的最終質量。離開了良好的軟件架構,你可能瞄準了正確的問題,卻使用了錯誤的解決方案。

在前端,架構的選擇好像就是框架的選擇,構建工具的選擇。可是拋開任何框架,或者本身要從頭開始搭建,你須要考慮下面問題:

程序組織

主要的類

數據設計

業務規則

用戶界面設計

資源管理

安全性

性能

可伸縮性

互用性

國際化/本地化

輸入輸出

錯誤處理

容錯性

架構的可行性

過分工程

是」買「仍是」造「?

複用性

變動策略

架構的整體質量

這上面的每個點水都很深,就拿錯誤處理來講,你的設計應該考慮到:

  • 錯誤處理是進行糾正仍是進行檢測?

  • 錯誤檢測是主動仍是被動?

  • 程序如何傳播錯誤?

  • 錯誤消息的處理有什麼約定?

  • 如何處理異常?

  • 在程序中,在什麼層次上處理異常?是在發現錯誤的時候處理?仍是傳遞錯誤到統一的地方處理?仍是沿函數調用鏈向上傳遞?

  • 每一個類在驗證其輸入數據的有效性方面須要負什麼責任?

  • 你是但願在運行環境內處理錯誤,仍是創建一套本身的機制?

天啦擼,架構師真不容易。

最後,架構不該該包含任何僅僅爲了取悅老闆的東西。

關鍵的」構建「決策

選擇編程語言

任何一種GPL都有跨界的能力,若是你愛折騰,你能夠用Python,用Haskell來寫前端,但這並非一個好主意。任什麼時候候,都不能爲了使用某種語言而選擇它。

編程約定

編程實現必須與指導該實現的架構保持一致,團隊必須使用同一套編碼規範,這點卻是比較容易作到,尤爲是在大公司。

你在技術浪潮中的位置

在技術浪潮前期,針對新興技術的編程語言和框架都比較少,程序員花費了大量時間,都是爲了弄清語言是如何工做的,而非編寫新的代碼。程序員還花了大量時間來繞過語言產品的bug、下層OS的bug以及其餘工具的bug。

在技術浪潮末尾,咱們有大量的編程語言和框架可選,擁有完善的錯誤檢查和調試工具以及自動化優化工具,以及各類學習資源和訓練課程。

舉個栗子,VR的開發如今正處在浪潮前期,而前端開發則處在浪潮之巔。

理解本身在浪潮中的位置,有助於本身更好的面對編程工做。若是在前期,你可能須要花大部分時間來」造輪子「或」修輪子」,若是在後期,你只須要關注編寫新功能。

編程工具不該該決定你的編程思路

「在一種語言上編程(programming in a language)」的程序員將他們的思想限制於」語言直接支持的那些構件」,若是語言工具是初級的,那麼程序員的思想也是初級的。

「深刻一種語言去編程(programming into a language)」的程序員首先決定他要表達的思想是什麼,而後決定如何使用特定語言提供的工具來表達這些思想。

選擇主要的構建實踐方法

構建實踐方法有不少,從編碼,團隊協做,質量保證,開發工具各個方面有意識的選擇最適合你的項目的實踐方法。

以上,是在編程以前的工做。

結語

編程前的工做看着有些無聊,但卻很是重要。以後會繼續分享本身的一些心得:

能夠很明顯的看出對於架構部分我基本是略過.....額,不過有趣的是,等再過兩三年本身水平提升了一個檔次以後,再回來看架構部分必然會有更深入的體會,如此也是記錄本身成長的一部分,善哉。

相關文章
相關標籤/搜索