麵條式代碼
麵條式代碼(英語:Spaghetti code)是軟件工程中反面模式的一種[1],是指源代碼的控制流程複雜、混亂而難以理解[2],尤其是用了很多GOTO、例外、線程、或其他無組織的分支。其命名的原因是因為程式的流向就像一盤麵一樣扭曲糾結。麵條式代碼的產生有許多原因,例如沒有經驗的程序設計師,及已經過長期頻繁修改的複雜程序。結構化編程可避免麵條式代碼的出現。
舉例
編輯以下是一段用BASIC寫的程序,是典型麵條式代碼的例子。程序在屏幕上顯示數字 1 到 10 及其對應的平方。由於有GOTO
語句,此程序需要配合行號才能知道程序的流向,也無法利用縮排的方式使程序比較容易閱讀。而且由於有跳轉指令,要執行的程序會由一個區域跳轉到另一個區域,而且在讀到跳轉指令前,很難事先知道程式會跳轉,此程式不易調試。現實世界中的麵條式代碼往往更加複雜,會大幅增加維護成本。
10 i = 0
20 i = i + 1
30 PRINT i; " squared = "; i * i
40 IF i >= 10 THEN GOTO 60
50 GOTO 20
60 PRINT "Program Completed."
70 END
以下程序則使用結構化控制,沒有GOTO
語句,因此可以縮進,增強程序的可讀性:
1 FOR i=1 TO 10
2 PRINT i;"squared=";i*i
3 NEXT i
4 PRINT "Program Completed."
5 END
程序中還是有由一個區域跳轉到另一個區域的情況,不過這種跳轉是可以預期的,也是標準的做法。使用FOR循環或子程序是處理程序控制流程的標準做法。若使用GOTO,就表示允許程序任意地跳轉。上述示例的代碼很短,實際使用的程式其源代碼更長,若是麵條式代碼的話,會相當難以維護。
匯編語言及腳本語言
編輯當使用各種匯編語言(及其底層的機器語言)時,編寫麵條式代碼會帶來更大的危險。其原因是由於這些低級語言很少有可以對應 FOR 循環或 WHILE 循環的機制。許多腳本語言也有類似的情況,例如 DOS 的批處理文件或者 OpenVMS 上的資料控制語言 (DCL)。
如果將結構化編程中的做法移植到匯編語言的程序,會顯著地增強可靠性和可維護性。例如限制 GOTO 的使用,只用 GOTO 來產生類似結構化程序設計中流程控制的效果、另外許多匯編語言都有提供子程序呼叫的機制,可以有類似過程式編程(Procedural programming)的效果。匯編語言一般都會有巨集,而且支持參數傳遞,以避免全局變量的使用,也可避免遠隔作用 (action at a distance)的反面模式。
使用高級語言編寫的程式可以利用一些標準流程控制的作法(如以上第2例的 For 循環),不過當編譯為匯編代碼或者機器代碼時,由於最後仍利用 GOTO 或 IF 之類的指令表示高級語言的標準流程控制,看起來仍會像麵條式代碼。因為編譯器會忠實地將程序的結構轉換為匯編代碼,所以,其他結構性較弱的語言遇到的程序流程難以辨識的問題,不會遇到。不過,如果程序優化過多,可能在縮小程序大小的同時,也影響其程序的結構。若配合代碼級調試使用,還可能會造成一些困難。
相關詞語
編輯餛飩式代碼
編輯餛飩式代碼(Ravioli code)指由許多鬆散連接的小部份構成的程序。餛飩式代碼可以和麵條式代碼作類比,後者用麵條來代表程序的結構,而前者用餛飩(Ravioli)來代表程序中的對象。這種代碼雖然滿足了低耦合性的要求,但是過度的分離與封裝導致過多的調用,使得堆棧容易變得臃腫,從而也增加了代碼閱讀的難度。
千層麵代碼
編輯千層麵代碼(Lasagna code)是指各層都很複雜的軟體。各層彼此相關性強,因此更改某一層時必須同步修改其他層[3]。
參見
編輯參考文獻
編輯- ^ William J. Brown, Raphael C. Malveau, Hays W. "Skip" McCormick, Thomas J. Mowbray (1998). AntiPatterns: refactoring software, architectures, and projects in crisis.(1st ed.). Wiley. ISBN 0471197130.
- ^ J. Stanley Warford (2009). Computer Systems.(4th ed.). Jones & Bartlett Publishers. ISBN 0763771449.
- ^ Tomov, Latchezar; Ivanova, Valentina. Teaching Good Practices In Software Engineering by Counterexamples. Computer Science and Education in Computer Science. October 2014, (1): 397–405 [5 March 2018].