面条式代码
举例
以下是一段用BASIC写的程序,是典型面条式代码的例子。程序在屏幕上显示数字1到10及其对应的平方。由于有GOTO指令,此程序需要配合行号才能知道程序的流向,也无法利用缩进(英语:Indent_style)的方式使程序较容易阅读。而且因为跳跃指令的关系,要运行的程序会不可预测的由一个区域跳到另一个区域,不易追踪。现实世界中的面条式代码往往更加复杂,会大幅增加维护的成本。
10i=020i=i+130PRINTi;" squared = ";i*i40IFi>=10THENGOTO6050GOTO2060PRINT"Program Completed."70END
以下则是使用结构化的控制架构后的程序,由于没有GOTO指令,程序已不需要行号,而且可以用缩进的方式,增加程序可读性:
PublicSubMain()ForiAsInteger=1To10Console.WriteLine("{0} squared = {1}",i,i^2)NextConsole.WriteLine("Program Completed.")EndSub
程序中还是有由一个区域跳到一个区域的情形,不过这种跳跃是可预期的,也是标准的作法。使用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及其他的流程控制指令。
国际C语言混乱代码大赛:一个设法写出让人难以理解C语言代码的比赛。
参考文献
本条目部分或全部内容出自以GFDL授权发布的《自由在线电脑词典》(FOLDOC)。
免责声明:以上内容版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。感谢每一位辛勤著写的作者,感谢每一位的分享。
- 有价值
- 一般般
- 没价值