面条式代码

面条式代码（）又稱祖傳代碼、屎山代碼，是软件工程中反面模式的一种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.，尤其是用了很多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）是指各層都很複雜的軟體。各層彼此相關性強，因此更改某一層时必须同步修改其他層。

參見
 结构化编程：程序中不使用 GOTO，只使用像 Loop, For 及其他的-{流程控制}-指令。
 国际C语言混乱代码大赛：一个设法写出让人难以理解的 C 语言代码的比赛。
组合子逻辑
柯里化
λ演算
极小化求值
求值策略

 参考文献 

外部連結
Go To Statement Considered Harmful. Edsger Dijkstra 提出有关面条式代码的缺点。
We don't know where to GOTO if we don't know where we've COME FROM by  R. Lawrence Clark from DATAMATION, December, 1973
Refactoring Java spaghetti code into Java bento code  将一个类中许多的代码分解为七个不同类的代码。

Category:反模式
Category:计算机编程