麵條式代碼
麵條式代碼(英語: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].