1. 程式人生 > 其它 >04程式設計師修煉之道:從小工到專家之四

04程式設計師修煉之道:從小工到專家之四

Chap5 彎曲,或折斷

解耦:任何一個單獨的模組儘量不要依賴其他模組的特性,除了有些特殊情況下會違背這個原則換取一定的效率。

元資料:用於將程式碼功能靈活化。將容易改變的、不確定的資料用“元資料”進行配置而不要固定地編織到程式碼中;可以將某些並非模組固定功能的邏輯(比如客戶的個性化需求)通過配置而非程式碼的方式表示,這樣就不用反覆為了適應需求而修改程式碼、重新編譯。可以時不時檢查載入新的配置以免修改配置便需要重啟的麻煩狀況。

時間的解耦:進行流程分析,分析各任務時間上的相互依賴,進行併發程式設計,可以提高程式的效率。要對全域性變數、靜態資料的訪問與呼叫進行保護。介面要設計得更整潔,避免介面對呼叫時間的依賴。

釋出/訂閱協議:某個模組只關心特定的事件,並對不同事件分別作出響應。模組通過“訂閱”(subscribe)某個事件對事件作出響應。而模組引發某個事件時,依次呼叫各個訂閱者通知事件發生。

MVC:將Model(資料模型), View(檢視)和Controller(檢視控制器)解耦。MVC模型雖然用於GUI開發,但可以更泛化地理解為Model為抽象資料模型;View為解釋模型的方式,向Model與Controller訂閱事件;Controller控制View並向Model提供新資料,向Model與View釋出事件。

黑板:將各個資訊放在一個資訊流裡,各模組與資訊流進行互動,從而可以達到統一簡便的互動,而不需要在各個模組之間兩兩規定嚴密的釋出/訂閱協議,釋出者與訂閱者不需要了解對方。

這個設計用於較為複雜,每個模組的行為都會帶來新的改變,隨時有可能有事件發生並引起其他模組的行為的系統,此時在各個模組之間一一設計介面幾乎不可能。

這個設計很優美,但我產生了兩個疑惑:這樣大的資料量是否會對資料的維護和模組的查詢帶來負擔?是否會出現資訊洩漏的風險?對於第一個問題,維護問題我沒有想好,但查詢可以通過良好地組織資料結構簡化;對於第二個問題,可以通過限制許可權得到改善,但似乎還是會有風險。

Chap6 當你編碼時

編碼過程中應該遵循的原則。

靠巧合程式設計:不可靠。不要使模組可能依賴特定的輸入資料、語境,否則模組的正常工作可能只是偶然。積極地查詢可能的問題並修改。

為了避免這個問題,編碼過程中要依靠可靠的、瞭解的東西,而不要碰巧拼湊一些程式碼,希望它能成功。比如如果不會使用某個第三方庫,應該去學習而非隨意堆積程式碼,試圖得到希望得到的結果。為模組編寫文件有利於發現隱藏的假設和巧合。

不要讓自己成為過去的程式碼的奴隸,尤其是在開發階段。對於模稜兩可、可能出問題的程式碼,要積極地進行檢查與重構。

演算法速率:這裡講到了對演算法執行時間進行O( )的估算,即資料結構課程中提到的時間複雜度。演算法速率的估算可以通過常識估算。如果演算法有多重迴圈,達到了O(n^2)甚至O(n^3)的時間複雜度,就要試著用分治法等方法將時間複雜度降低。不過演算法速率的估算是理論的極端情況,實際的演算法速率要通過測試來獲取。可以使用code profiler這一工具獲得演算法中不同步驟的執行次數。

不過快的演算法速率並不一定是好的。有時資料集很小,O(n)與O(ln n)級的演算法差別很小,演算法速率反而受常數影響更大。這時花過多的時間構想一個高效的演算法是沒有實際意義的,根據實用主義的原則不必這麼做。當然如果隨著系統的增加該演算法成了效率瓶頸,進行優化就很有必要。

重構:重寫、重做及重新架構程式碼。在出現這些情況時需要重構:程式碼有自重複、功能不正交、效能不夠、內容過時。重構可能是痛苦的,但不要為了一時的痛苦放棄重構,因為有問題的程式碼可能帶來更多問題。重構是將原本能夠工作的程式碼進行修改,所以很可能是危險的。重構要遵循以下原則:不能加入新功能。保持有一系列良好的測試,這樣出現任何問題時都可以快速發現。將重構拆分成許多個短小的重構,並在進行每個小改動之後進行測試,以發現可能的錯誤。

易於測試的程式碼:進行模組的組裝前,對模組進行單元測試,檢查其在各種情況下的行為非常重要。對於有依賴關係的模組,從最小的模組向上層層單元測試可以更容易定位錯誤。建議根據合約對程式碼進行測試,利用合約的前條件、後條件和不變數設定可以很容易確定測試內容。

編寫程式碼的同時就應該編寫程式碼的單元測試。

編寫大型專案時,為了方便單元測試,應該使用測試裝備以動態構建測試。比如可以編寫一個類,負責測試的常用功能。測試裝備有必要提供以下功能:用以指定設定測試條件與清理測試現場的方法,用以選擇個別或全部測試的方法,分析輸出是否是預期結果的方法,生成標準化錯誤輸出的方法。測試應該是可組合的。

在編寫程式碼的過程中,常會加入一些即興除錯,如printf語句。不要拋棄這些除錯語句,將它們加入單元測試。編碼過程中出現過問題的部分在執行中可能會再出問題。

程式碼部署好之後也不要忘記測試。要構建執行日誌以方便記錄執行狀態,日誌應該風格良好以方便解析。要構建可用於診斷執行狀態的服務。

邪惡的嚮導:依靠開發環境提供的“嚮導”進行編碼是依靠巧合而程式設計。可以使用封裝良好的第三方庫,但在不理解gui生成的“嚮導程式碼”時不要使用它,因為它會變成程式碼有機的一部分,並隨時可能帶來問題。