軟體編程原則

關於編程原則,實際上並沒有一套統一的原則可以適用於所有的系統,不同應用場景、不同架構的系統,對於編程原則的要求相差還是比較大,看看以下著名的17條UNIX編程原則和NASA 的10條安全編碼準則,大家就可想而知了。當然,兩者並非對比,而是側重點不同。

UNIX哲學17條原則

1、模塊化原則(Rule of Modularity)

開發人員應該使用定義良好的界面連接簡單的部分來構建程序,所以問題是本地的,部分程序可以在未來的版本中替換以支持新的功能。此規則旨在節省調試複雜,長期且不可讀的代碼的時間。

2、清晰原則(Rule of Clarity)

開發人員應該編寫清晰的程序,就好像最重要的溝通是向開發人員讀取和維護程序,而不是計算機。這個規則的目的是使代碼在將來的代碼中儘可能易讀和易理解。

3、和解原則(Rule of Composition)

開發人員應該編寫能夠與其他程序輕鬆通信的程序。這條規則的目的是讓開發人員把項目分解成小而簡單的程序,而不是過於複雜的單片程序。

4、分離規則(Rule of Separation)

開發者應該將程序的機制與程序的策略分開;一種方法是將程序分成與該接口通信的前端接口和後端引擎。這條規則旨在通過允許改變策略,儘可能降低操作機制的不穩定性來防止錯誤引入。

5、簡單規則(Rule of Simplicity),

開發人員應該設計簡單的方法,通過尋找方法將程序系統分解成小而直接的合作件。這條規則的目的是阻止開發者寫作“複雜而美麗的複雜性”,這是現實中容易出錯的程序。

6、簡約規則(Rule of Parsimony)

開發人員應該避免編寫大型程序。這一規則的目的是防止由於項目的所有者不願拋棄顯著的大量工作而導致失敗或次優方法的過度投資。較小的程序不僅易於編寫,優化和維護,棄用時更容易刪除。

7、透明度原則(Rule of Transparency)

開發人員應該設計可見性和可發現性,通過編寫這樣一種方式,他們的思維過程可以清楚地被未來的項目開發人員所看到,並使用輸入和輸出格式,以便識別有效輸入和正確輸出。此規則旨在減少調試時間並延長程序的使用壽命。

8、穩健性規則(Rule of Robustness)

開發人員應該通過設計透明和可發現性來設計強大的程序,因為易於理解的代碼更容易對複雜程序中無法預見的意外情況進行壓力測試。此規則旨在幫助開發人員構建強大,可靠的產品。

9、表示規則(Rule of Representation)

開發人員在面對選擇時應該選擇使數據更復雜,而不是程序的邏輯,因為與複雜的邏輯相比,人類更容易理解複雜的數據。這條規則的目的是使任何開發項目的開發人員都可以使程序更易讀,從而使程序得以維護。

10、最小驚喜規則(Rule of Least Surprise)

開發人員應該根據潛在用戶的預期知識設計程序。例如,計算器程序中的“+”應該總是指“加法”。該規則旨在鼓勵開發人員構建易於使用的直觀產品。

11、沉默的規則(Rule of Silence)

開發人員應該設計程序,以免打印不必要的輸出。這個規則旨在允許其他程序和開發者從程序的輸出中挑出他們需要的信息,而不必分析冗長。

12、修理規則(Rule of Repair)

開發人員應該設計失敗的程序,易於本地化和診斷,換句話說就是“失敗”。這條規則旨在防止程序的錯誤輸出成為輸入,並破壞未被檢測到的其他代碼的輸出。

13、經濟規則(Rule of Economy)

開發人員應該重視開發人員在機器上的時間,因為與上世紀70年代的價格相比,今天的機器週期相對便宜。這條規則旨在降低項目的開發成本。

14、生成規則(Rule of Generation)

開發人員應該避免手動編寫代碼,而是編寫抽象的高級程序來生成代碼。此規則旨在減少人為錯誤並節省時間。

15、優化規則(Rule of Optimization)

開發人員應該在打磨軟件之前製作原型。這條規則旨在防止開發者花費太多時間來獲得邊際收益。

16、規則的多樣性(Rule of Diversity)

開發者應該設計他們的程序是靈活的,開放的。這條規則的目的是使程序更加靈活,使其能夠以開發者所期望的方式使用。

17、可擴展性規則(Rule of Extensibility)

開發人員應該通過使其協議可擴展來設計未來,允許輕鬆插件,而無需修改其他開發人員的程序架構。

NASA 的10條安全編碼準則

由NASA的首席科學家Gerard J. Holzmann制定

1、簡化控制流程

使用盡可能精簡的控制流程設計: 不要使用 setjmp 或 longjmp、goto 語句,以及直接或間接的遞歸調用。

2、使用固定的循環次數上限

所有的循環必須有一個固定的上限。 必須可以被檢測工具靜態地證實,該循環的迭代器不會超出上限值,如果不能被靜態地證實,則可以認為違背該規則。

3、不使用動態內存分配

不要在初始化完成後進行動態內存分配。

4、不使用冗長的函數

要求函數的代碼長度按照每個聲明佔一行、每個語句佔一行這樣的標準參考格式,能在一頁紙上打印出來。這意味著函數的代碼不應超過60行。

5、低斷言密度

代碼中的斷言密度(assertion density)應低至平均每個函數2個斷言。斷言用於檢查實際執行過程中絕不應出現的異常狀況,必須定義為Boolean測試。當斷言失敗時,應執行明確的恢復操作。如果靜態檢查工具發現斷言永遠不可能失敗或永遠不會被觸發,則可認為未遵守該原則。

該原則同時也是數據隱蔽(Data hiding)的基本原則。所有數據對象必須以儘可能小的範圍級別進行聲明。

7、檢查參數和返回值

應在每次調用函數後檢查非void函數的返回值,並在每個函數內部檢查參數的有效性。

8、限制預處理程序的使用

預處理程序(Preprocessor)只能在頭文件和宏定義中使用。遞歸的宏調用、符號拼接,以及可變參數列表均不允許使用。

通常不建議使用條件編譯指令,如果代碼中不能夠避免時,必須有基於工具的檢查器進行標記,並有充足的理由。

9、限制指針的使用

必須限制指針的使用,不允許有超過一級的指針解引用操作。指針解引用操作不能隱藏在typedef類型聲明或宏定義中。不允許使用函數指針。

10、編譯所有代碼

從開發工作第一天開始,就必須對所有代碼進行編譯。必須啟用編譯器的警告功能,並使用最細緻的檢查選項。在此設置之下,代碼必須零警告編譯通過。代碼必須使用源代碼靜態分析工具,每天檢查一次以上,且零警告通過。


分享到:


相關文章: