面条式代码

维基百科,自由的百科全书
跳转至: 导航搜索
一盤扭曲糾結的義大利麵,麵條式代碼也是如此的扭曲糾結。

麵條式代碼Spaghetti code)是軟體工程反面模式的一種[1],是指一個程式碼控制結構複雜、混亂而難以理解[2],尤其是用了很多GOTO例外執行緒、或其他無組織的分歧架構。其命名的原因是因為程式的流向就像一盤麵一樣的扭曲糾結。麵條式代碼的產生有許多原因,例如沒有經驗的程式設計師,及已經過長期頻繁修改的複雜程式。結構化程式設計可避免麵條式代碼的出現。

舉例[编辑]

以下是一段用BASIC寫的程式,是典型麵條式代碼的例子。程式在螢幕上顯示數字1到10及其對應的平方。由於有GOTO指令,此程式需要配合行號才能知道程式的流向,也無法利用縮排英语Indent_style的方式使程式較容易閱讀。而且因為跳躍指令的關係,要執行的程式會不可預測的由一個區域跳到另一個區域,不易追蹤。現實世界中的麵條式代碼往往更加複雜,會大幅增加維護的成本。

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指令,程式已不需要行號,而且可以用縮排的方式,增加程式可讀性:

Public Sub Main()
  For i As Integer = 1 To 10
    Console.WriteLine("{0} squared = {1}", i, i ^ 2)
  Next
  Console.WriteLine("Program Completed.")
End Sub

程式中還是有由一個區域跳到一個區域的情形,不過這種跳躍是可預期的,也是標準的作法。使用FOR迴圈函式是處理程式流程控制的標準作法。若使用GOTO,也就表示允許程式任意的跳躍。上述範例的程式碼很短,實際使用的程式其程式碼更長,若是麵條式代碼的話會相當難以維護。

組合語言及腳本語言[编辑]

當使用各種組合語言(及其底層的機械碼)時,撰寫麵條式代碼會帶來更大的危險。其原因是由於這些低階語言很少有可以對應FOR迴圈WHILE迴圈的機能。許多腳本語言也有類似的情形,例如DOS的批次檔或是OpenVMS上的DCL

若將結構化程式設計中的作法移植到組合語言的程式,會對可靠性及可維護性有顯著的改善。例如限制GOTO的使用,只用GOTO來產生類似結構化程式設計中流程控制的效果、另外許多組合語言都有提供函式呼叫的機制,可以有類似程序化程式設計(Procedural programming)的效果。組合語言一般都會有巨集,而且支援參數傳遞,以避免全域變數的使用,也可避免遠隔作用(action at a distance)的反面設計模式

使用高階語言撰寫的程式可以利用一些標準流程控制的作法(如以上第2例的for loop),不過當組譯為組合語言或機器碼時,由於最後仍利用GOTO或IF之類的指令表示高階語言的標準流程控制,看起來會像是麵條式代碼。因為組譯器會忠實的將程式的結構轉換為組合語言,因此不會遇到其他結構性較弱的語言所遇到,程式流程難以辨識的問題。不過,若是程式作了過多的最佳化,可能在縮小程式大小的同時,也影響其程式的結構,若配合 source-level debugger 使用,有時會因些造成一些困擾。

餛飩式代碼[编辑]

餛飩式代碼(Ravioli code)是指程式中是由許多小的、鬆散連接的部份所構成。餛飩式代碼可以和麵條式代碼作比較,後者用麵條來代表程式的結構,而前者用餛飩(Ravioli)來代表程式中的物件

參見[编辑]

  • 結構化程式設計 程式中不使用goto,只使用像 loop, for 及其他的流程控制指令。

参考文献[编辑]

  1. ^ 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.
  2. ^ J. Stanley Warford (2009). Computer Systems‎. (4th ed.). Jones & Bartlett Publishers. ISBN 0763771449.

本條目部分或全部内容出自以GFDL授權發佈的《自由線上電腦詞典》(FOLDOC)。

外部連結[编辑]