《代碼大全》是本經典著做,不一樣階段,不一樣水平的人看了必然會有不一樣的感覺。像我這種新手最關注的多是代碼質量部分,而高手可能會更加關注架構。本系列博客是本身在學習時的一些記錄和感想,偏前端,或許不少內容你都瞭解了,但你必定會發現亮點。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)」的程序員首先決定他要表達的思想是什麼,而後決定如何使用特定語言提供的工具來表達這些思想。
構建實踐方法有不少,從編碼,團隊協做,質量保證,開發工具各個方面有意識的選擇最適合你的項目的實踐方法。
以上,是在編程以前的工做。
編程前的工做看着有些無聊,但卻很是重要。以後會繼續分享本身的一些心得:
能夠很明顯的看出對於架構部分我基本是略過.....額,不過有趣的是,等再過兩三年本身水平提升了一個檔次以後,再回來看架構部分必然會有更深入的體會,如此也是記錄本身成長的一部分,善哉。