跳转到内容

面条式代码:修订间差异

维基百科,自由的百科全书
删除的内容 添加的内容
 
(未显示16个用户的32个中间版本)
第1行: 第1行:
{{noteTA
{{NoteTA
|G1=IT
|G1 = IT
|G2 = 地名
|1 = zh-hant:義大利直麵; zh-cn:意大利直面; zh-tw:義大利麵; zh-hk:意大利粉; zh-sg:意大利面;
}}
}}
[[file:Spaghetti.jpg|thumb|一扭曲糾結的[[義大利麵]],麵條式代是如此的扭曲糾結。]]
[[file:Spaghetti.jpg|thumb|一扭曲纠结的[[義大利麵]],面条式代同样地扭曲纠结。]]


'''麵條式代'''('''Spaghetti code''')是[[軟體工程]]中[[反面模式]]的一<ref name="William">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.</ref>,是指一個[[程式碼]]的[[控制結構]]複雜、混以理解<ref name="Stanley">J. Stanley Warford (2009). ''Computer Systems‎''. (4th ed.). Jones & Bartlett Publishers. ISBN 0763771449.</ref>,尤其是用了很多[[Goto|GOTO]]、[[例外]]、[[執行緒]]、或其他無組織的[[分歧架構]]。其命名的原因是因程式的流向就像一麵一樣的扭曲糾結麵條式代生有多原因,例如經驗的程式設計師,及已經過長繁修改的複雜。[[結構化程式設計]]可避免麵條式代的出
'''面条式代'''({{Lang-en|Spaghetti code}})是[[软件工程]]中[[反面模式]]的一<ref name="William">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.</ref>,是指[[源代码]]的[[控制流程]]复杂、混以理解<ref name="Stanley">J. Stanley Warford (2009). ''Computer Systems''.(4th ed.. Jones & Bartlett Publishers. ISBN 0763771449.</ref>,尤其是用了很多[[Goto|GOTO]]、[[异常处理|例外]]、[[线程]]、或其他无组织的[[分支 (計算機科學)|分支]]。其命名的原因是因程式的流向就像一麵一扭曲纠结面条式代生有多原因,例如经验的程序设计师,及已经过长繁修改的复杂。[[结构程]]可避免面条式代的出


==例==
==例==
以下是一段用[[BASIC]]的程,是典型麵條式代的例子。程幕上字1到10及其對應的平方。由有<code>[[Goto|GOTO]]</code>指令,此程需要配合[[行號]]才能知道程的流向,也法利用[[縮排]]的方式使程式較容易閱讀。而且因為指令的關係,要行的程式會不可預測的由一個區域跳到另一個區域,不易追蹤現實世界中的麵條式代往往更加複雜大幅增加維護的成本。
以下是一段用[[BASIC]]的程,是典型面条式代的例子。程幕上 1 10 及其对应的平方。由有<code>[[Goto|GOTO]]</code>语句,此程需要配合[[行號 (程式語言)|行号]]才能知道程的流向,也法利用[[縮進風格|縮排]]的方式使程序比较容易阅读。而且由于有指令,要行的程序会由一个区域跳到另一个区域,而且在讀到跳转指令前,很難事先知道程式會跳轉,此程式不易调试现实世界中的面条式代往往更加复杂大幅增加维护成本。
<source lang="qbasic">
<syntaxhighlight lang="qbasic">
10 i = 0
10 i = 0
20 i = i + 1
20 i = i + 1
第16行: 第18行:
60 PRINT "Program Completed."
60 PRINT "Program Completed."
70 END
70 END
</syntaxhighlight>
</source>
以下則是使用結構控制架構後的程式由於沒有<code>GOTO</code>指令程式已不需要行號,而且可以用縮排的方式,增:
以下程序则使用结构化控制,有<code>GOTO</code>语句因此可以缩进,增序的
<source lang="vbnet">
<syntaxhighlight lang="gwbasic">
1 FOR i=1 TO 10
Public Sub Main()
2 PRINT i;"squared=";i*i
For i As Integer = 1 To 10
3 NEXT i
Console.WriteLine("{0} squared = {1}", i, i ^ 2)
4 PRINT "Program Completed."
Next
5 END
Console.WriteLine("Program Completed.")
</syntaxhighlight>
End Sub
是有由一个区域跳个区域的情,不过这种是可以预期的,也是标准法。使用[[FOR迴圈|FOR循环]]或[[子程]]是理程[[控制流程]]的标准做法。若使用GOTO,就表示允任意。上述例的代码很短,实际使用的程式其源代码,若是面条式代话,会当难维护
</source>
是有由一個區域跳到一個區域的情,不過這種是可期的,也是標準法。使用[[FOR迴圈]]或[[子程式|函式]]是理程[[流程控制]]的標準作法。若使用GOTO,就表示允任意。上述例的程式碼很短,實際使用的程式其程式碼,若是麵條式代話會當難維護


==組合語言及言==
==汇编语言及言==
使用各[[組合語言]](及其底的[[機械碼]])撰寫麵條式代碼會帶來更大的危。其原因是由於這些[[低階語言]]很少有可以對應[[FOR迴圈]]或[[WHILE迴圈]]的機能多[[言]]也有似的情,例如[[DOS]]的批次檔[[OpenVMS]]上的[[DCL]]。
使用各[[汇编语言|汇编語言]](及其底的[[机器语言]])编写面条式代码会带来更大的危。其原因是由于这些[[低级语言]]很少有可以对应 [[FOR迴圈|FOR 循环]]或 [[WHILE迴圈|WHILE 循环]]的机制多[[言]]也有似的情,例如 [[DOS]] 的批处理文件[[OpenVMS]] 上的[[資料控制語言]] (DCL)


若將[[結構化程式設計]]中的法移植到組合語言的程會對可靠性維護有顯著的改善。例如限制GOTO的使用,只用GOTO來產結構化程式設計中-{流程控制}-的效果、另外組合語言都有提供[[函式]]呼叫的制,可以有似[[程序化程式設計|-{序}-化程式設計]](Procedural programming)的效果。組合語言一般都有[[巨集]],而且支援參數傳遞,以避免[[全域變數]]的使用,也可避免[[遠隔作用 (計算機科學)|隔作用]](action at a distance)的[[反面模式|反面設計模式]]。
如果将[[结构程]]中的法移植到汇编语言的程会显著地增强可靠性维护性。例如限制 GOTO 的使用,只用 GOTO 来产结构化程序设计中-{流程控制}-的效果、另外汇编语言都有提供[[子程序]]呼叫的制,可以有似[[程式程]](Procedural programming)的效果。汇编语言一般都有[[巨集]],而且支持参数传递,以避免[[全局变量]]的使用,也可避免[[遠隔作用 (計算機科學)|隔作用]] (action at a distance)的[[反面模式]]。


使用[[高階語言]]撰寫的程式可以利用一些標準流程控制的作法(如以上第2例的for loop),過當組譯為組合語言碼時,由仍利用GOTO或IF之的指令表示高階語言的標準流程控制,看起來會是麵條式代。因為組譯實的將結構轉換為組合語言因此不會遇到其他結構弱的遇到流程以辨問題。不若是式作了過多的[[最化]],可能在小程大小的同,也影其程結構,若配合 source-level debugger 使用,有時會因些造成一些困
使用[[高级语言]]编写的程式可以利用一些标准流程控制的作法(如以上第2例的 For 循环),过当编译为汇编代码者机代码时,由仍利用 GOTO IF 的指令表示高级语言的标准流程控制,看起来仍会面条式代。因为编译实地将结构转换为汇编代码,所以,其他结构弱的言遇到流程以辨问题,不会遇到。不如果[[最优化|优化]]过多,可能在小程大小的同,也影其程结构。若配合代码级调试使用,还可能会造成一些困


==餛飩式代碼==
==相關詞語==
===餛飩式代碼===
餛飩式代碼(Ravioli code)是指程式中是由許多小的、鬆散連接的部份所構成。餛飩式代碼可以和麵條式代碼作比較,後者用麵條來代表程式的結構,而前者用[[意大利餃|餛飩]](Ravioli)來代表程式中的[[对象 (计算机科学)|物件]]。
馄饨式代码(Ravioli code)指由许多松散连接的小部份构成的程序。馄饨式代码可以和面条式代码作类比,后者用面条来代表程序的结构,而前者用[[意大利餃|馄饨]](Ravioli)来代表程序中的[[对象 (计算机科学)|对象]]。这种代码虽然满足了低[[耦合性 (計算機科學)|耦合性]]的要求,但是过度的分离与封装导致过多的调用,使得[[呼叫堆疊|堆栈]]容易变得臃肿,从而也增加了代码阅读的难度。
===千層麵代碼===
{{Main|抽象層|層 (物件導向設計)}}
千層麵代碼(Lasagna code)是指各層都很複雜的軟體。各層彼此相關性強,因此更改某一層时必须同步修改其他層<ref name="Latchezar18">{{cite journal|last1=Tomov|first1=Latchezar|last2=Ivanova|first2=Valentina|title=Teaching Good Practices In Software Engineering by Counterexamples|journal=Computer Science and Education in Computer Science|date=October 2014|issue=1|pages=397–405|url=https://www.researchgate.net/publication/301298530|access-date=5 March 2018}}</ref>。


==參見==
==參見==
* [[結構化程式設計]] 中不使用<code>goto</code>,只使用像 loop, for 及其他的-{流程控制}-指令。
* [[结构程]]中不使用 <code>GOTO</code>,只使用像 Loop, For 及其他的-{流程控制}-指令。
* [[国际C语言混乱代码大赛]]:一个设法写出让人难以理解的 C 语言代码的比赛。
<!--* [[International Obfuscated C Code Contest]] A competition to produce pleasingly obscure C code.-->
*[[组合子逻辑]]
<!--* [[Spaghetti with Meatballs (programming)]] Twisted, tangled and unstructured code, that also includes objects.-->
*[[柯里化]]
*[[λ演算]]
*[[极小化求值]]
*[[求值策略]]


== 参考文献 ==
== 参考文献 ==
第48行: 第57行:


==外部連結==
==外部連結==
*[http://www.acm.org/classics/oct95/ Go To Statement Considered Harmful]. [[Edsger Dijkstra]]提出有關麵條式代的缺
*[https://web.archive.org/web/20070703050443/http://www.acm.org/classics/oct95/ Go To Statement Considered Harmful]. [[Edsger Dijkstra]] 提出有关面条式代的缺
*[http://www.fortran.com/fortran/come_from.html ''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]
*[https://web.archive.org/web/20180716171336/http://www.fortran.com/fortran/come_from.html ''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]
*[http://yost.com/computers/java/java-spaghetti/ Refactoring Java spaghetti code into Java bento code] 個類別多的程式分解不同類別程式
*[http://yost.com/computers/java/java-spaghetti/ Refactoring Java spaghetti code into Java bento code] {{Wayback|url=http://yost.com/computers/java/java-spaghetti/ |date=20210117060538 }} 将个类多的代码分解不同代码。



[[Category:反模式]]
[[Category:反模式]]

2023年1月19日 (四) 03:29的最新版本

一盘扭曲纠结的義大利直麵,面条式代码也同样地扭曲纠结。

面条式代码(英語: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]

參見

[编辑]

参考文献

[编辑]
  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.
  3. ^ 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]. 

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

外部連結

[编辑]