跳转到内容

面条式代码

本页使用了标题或全文手工转换
维基百科,自由的百科全书

这是本页的一个历史版本,由134.148.75.30留言2013年8月28日 (三) 10:57 參考來源编辑。这可能和当前版本存在着巨大的差异。

一盘扭曲纠结的义大利面,面条式代码也是如此的扭曲纠结。

面条式代码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指令,程式已不需要行号,而且可以用缩排的方式,增加程式可读性:

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)来代表程式中的物件

参见

参考文献

  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)。

外部链接