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

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

Chap2 注重實效的途徑

程式需要遵守的實用主義原則。

重複的危害:如果某個事物在程式碼中重複多次,就可能會在維護過程中帶來問題,因為改動了一處而忘記改動另一處造成自相矛盾。這加大了維護難度。要遵守DRY原則,即Don’t repeat yourself。

重複通常由這些東西引起:

強加的重複,由文件或使用者需求決定。這通常可以依照情況消除。需要重複表示的資訊可以用元資料schema與程式碼生成器消除重複。註釋與程式碼會重複,但實際上這種重複沒有必要:註釋不應重複程式碼中顯而易見的東西,而應該表達更高階的東西。文件與程式碼也會重複,可以利用文件生成工具。有些語言會強加一些重複,這比較難解決,只能依情況而定,一些基本的技術是cpp中不要在其他檔案中引用函式,而應該使用標頭檔案。

無意的重複,由設計的疏忽造成,需要積極的檢查和重構。如果為了效能需要違反DRY原則,記得將重複本地化,不要洩漏到模組外,並保持模組內行為良好。

無耐性的重複,可能造成遠大於一時麻煩的痛苦後果。程式設計師要學會約束自己。

開發者之間的重複,需要加強開發者之間的溝通。

正交性:指系統各同層次的元件之間沒有依賴關係,改變一個不影響另一個。如果系統不符合正交性,測試與維護會非常痛苦。而正交性的系統在出問題時更容易隔離修復,進行拓展時也不必改動已有模組,增加了生產力。

為了達到正交性,需要將團隊分為幾個清晰的小組分別工作,對系統進行模組化的設計。可以通過詢問“討論某個改動時需要設計多少人”判斷小組分工是否正交,通過詢問“改動某個模組背後的需求,會有多少模組受到影響?”判斷系統設計是否正交。

引入第三方庫時可能會破壞正交性,要小心不要使第三方庫對整體程式碼造成改動。如果第三方庫的介面存在問題,可以將第三方庫用適合自己程式碼的方式進行封裝。

編碼也有可能破壞正交性,需要注意:使程式碼保持解耦,除了需要的功能不要暴露其它細節。避免使用全域性資料。避免編寫相似的函式。

對專案進行測試與debug也可以檢查專案的正交性。如果測試或修正一個小模組會帶來許多其它的影響,那麼系統不夠正交。

正交性同樣適用於文件,文件內容與表達形式應該解耦。這讓我想到了markdown……

可撤銷性:許多需求會改變,許多政策會改變,所以編寫專案時任何決策都應該可以撤銷。專案結構應該保持靈活,不要依賴某個已有決策。

曳光彈:這個比喻有點晦澀。作者介紹了一種方法,編碼之初先搭建一個大致框架,然後慢慢填充編碼。這樣既可以方便編碼,又可以隨時與使用者溝通專案是否符合他們的需求。假如現有成果不符合需求,可以立馬進行修改,而不必等程式碼基本固定時候再進行重構。

原型與便箋:不同於曳光彈,曳光彈在使用之後繼續保留,只是逐漸“生長”成更完整的系統。原型是為了分析某個功能或需求建立的簡化模型,將細節遮蔽以方便分析,用來找到最好的實現方式,然後便丟棄不用。如分析UI需求時先用繪圖板確定最合適的UI,再用編碼實現。

領域語言:任何領域都有自己的語言,如用於配製的語言,用於文件的語言,用於描述需求的語言。可以發展一種小型語言。小型語言分兩種,配置語言方便解析但難以閱讀,命令語言相當於小型的指令碼語言,更近似於自然語言,但解析難度更高。小型語言可以是獨立的語言,也可以嵌入高階語言的程式碼,方便直接執行。

這是一個非常有趣的設想,然而很可惜,在我們的專案中,受限於我們的專案規模,這個設想不太可行。然而這給了我兩個啟發:

1. 進行程式設計時,首先將使用者需求抽象化。使用者需求常常是用自然語言表達的,通常包含許多複雜的要求,如在某些情況下將某個資料傳輸到另一個伺服器,在某些情況下丟棄資料,在某些情況下反饋警告等。直接試圖將自然語言描述的需求轉化成程式碼很可能會非常困難,這時候先將需求抽象成一個無關具體細節實現的邏輯框架會更容易,不管是流程框圖、虛擬碼還是別的什麼。這也是自頂而下的思想。

2. 很多時候編寫程式碼需要滿足的需求並不是使用者的,而是直接對接的下一層的需求。比如負責資料庫層的程式設計師可能需要滿足負責演算法層的程式設計師的需求。在這種情況下,交流時需要儘量良好地描述需求的邏輯。這也需要清晰的層與層之間的介面以及風格良好的文件。

3. 模組與模組之間的資訊交流需要清晰、易於解析並易於擴充套件。

估算:要學會估算。估算的方法在於限定問題的情景範圍,對系統建立模型,對模組進行拆分並分別估算,抹去可忽略不計的量。估算不需要過於精確,但需要細心。