Mã spaghetti
**Mã spaghetti** (Spaghetti code) là một cụm từ mang tính khinh miệt (en) cho mã nguồn có tính phi cấu trúc và khó bảo trì. Mã spaghetti có thể được gây ra bởi vài yếu tố, chẳng hạn như do bản yêu cầu dự án có tính không ổn định, thiếu quy tắc phong cách lập trình, và do người viết không đủ năng lực hoặc kinh nghiệm.

Ý nghĩa
-------

Mã mà dùng quá mức các câu lệnh GOTO (en) hơn là các cấu tạo lập trình có cấu trúc – kết quả sinh ra là các chương trình lộn xộn và không thể bảo trì được – thì hay được gọi là mã spaghetti. Mã như vậy có cấu trúc điều khiển phức tạp và rối rắm, kết quả sinh ra là một luồng chương trình mà về mặt khái niệm thì giống như một bát mì spaghetti – xoắn và rối. Trong một xuất bản năm 1980 của Cục Tiêu chuẩn Quốc gia Hoa Kỳ, cụm từ **chương trình spaghetti** được sử dụng để mô tả các chương trình trước đây có "các tệp bị phân mảnh và rải rác". Mã Spaghetti cũng có thể được dùng để mô tả một phản mô thức (en) trong đó mã hướng đối tượng được viết theo phong cách thủ tục, chẳng hạn như bằng cách tạo các lớp có các phương thức quá dài và bừa bãi, hoặc vứt bỏ đi các khái niệm hướng đối tượng như đa hình. Sự hiện diện của hình thức mã spaghetti này có thể làm giảm đáng kể tính dễ lĩnh hội của một hệ thống.

Lịch sử
-------

Người ta không rõ rằng từ khi nào mà cụm từ mã spaghetti được sử dụng phổ biến; tuy nhiên, một số tài liệu tham khảo xuất hiện vào năm 1977 bao gồm *Macaroni is Better Than Spaghetti* bởi Steele được xuất bản trong 'Biên bản lưu' của hội nghị chuyên đề năm 1977 về trí năng nhân tạo và ngôn ngữ lập trình. Trong cuốn sách năm 1978 *A primer on disciplined programming using PL/I, PL/CS, and PL/CT*, Richard Conway đã sử dụng thuật ngữ này để mô tả các kiểu chương trình rằng "có cùng cấu trúc sạch có tính logic giống như một đĩa mì spaghetti", một cụm từ được lặp đi lặp lại trong cuốn sách năm 1979 *An Introduction to Programming* mà ông là đồng tác giả với David Gries (en). Trong bài báo khoa học năm 1988 *A spiral model of software development and enhancement*, thuật ngữ này được sử dụng để mô tả sự thực hành trước đây của *mô hình mã và sửa lỗi* (code and fix model) – nói về sự thiếu việc kế hoạch của nó, và cuối cùng đã dẫn đến sự phát triển của mô hình thác nước. Trong cuốn sách năm 1979 *Structured programming for the COBOL programmer*, tác giả Paul Noll sử dụng các cụm từ *mã spaghetti* và *tổ của chuột* làm các từ đồng nghĩa để mô tả mã nguồn có cấu trúc kém.

Trong hội nghị *Ada – Europe '93*, ngôn ngữ Ada đã được mô tả là nó ép lập trình viên phải "tạo ra mã code dễ hiểu, thay vì mã spaghetti", vì cơ chế lan truyền ngoại lệ (exception) mang tính hạn chế của nó.

Vào năm 1981 trong một bài viết biếm nhại các ngôn ngữ máy tính trong sách *The Technic Michigan* có tiêu đề "BASICally speaking...FORTRAN bytes!!", tác giả đã mô tả FORTRAN là "bằng chứng rành rành rằng các nhà đồng sáng lập của IBM là người Ý, vì nó toàn là từ mã spaghetti mà ra cả".

Cụm từ có liên quan
-------------------

### Mã Ravioli (Ravioli code)

Mã Ravioli là một thuật ngữ riêng cho lập trình hướng đối tượng. Nó mô tả mã bao gồm các lớp có cấu trúc tốt, về mặt cô lập thì dễ hiểu, nhưng về mặt tổng thể thì lại khó hiểu.

### Mã Lasagna (Lasagna code)

Mã Lasagna dùng để chỉ mã có các tầng lớp rất phức tạp và đan xen với nhau, đến nỗi việc tạo ra một thay đổi trong một tầng lớp sẽ đòi hỏi phải thay đổi trong tất cả các tầng lớp khác.

Ví dụ
-----

Đoạn mã dưới đây được coi là một ví dụ thông thường của mã spaghetti trong ngôn ngữ BASIC. Chương trình in từng số từ 1 đến 100 lên màn hình cùng với bình phương của nó. Ở đây việc thụt đầu dòng không hề được sử dụng để làm rõ sự khác nhau giữa nhiều hành động khác nhau do mã lệnh thực hiện, và các câu lệnh `GOTO` của chương trình tạo ra một sự lệ thuộc chặt chẽ vào số dòng (en). Luồng thực thi từ miền này sang miền khác khó dự đoán hơn. Sự xuất hiện của mã spaghetti trong thế giới thực thì phức tạp hơn và có thể thêm rất nhiều vào chi phí bảo trì cho chương trình. 

```
1 i=0
2 i=i+1
3 PRINT i; "bình phương=";i\*i
4 IF i>=100 THEN GOTO 6
5 GOTO 2
6 PRINT "Chương trình đã hoàn tất."
7 END

```
 Đây cũng là mã trên nhưng được viết lại theo kiểu lập trình có cấu trúc: 

```
1 FOR i=1 TO 100
2 PRINT i;"bình phương=";i\*i
3 NEXT i
4 PRINT "Chương trình đã hoàn tất."
5 END

```
 Chương trình trên đây cũng nhảy từ miền này sang miền khác, nhưng bước nhảy đấy thì mang tính hình thức và dễ dự đoán hơn, bởi vì vòng lặp for (en) và hàm đều cung cấp sự điều khiển luồng có kiểm soát còn câu lệnh *goto* lại khuyến khích điều khiển luồng tùy ý.

Mặc dù ví dụ trên này thì nhỏ, các chương trình trong thế giới thực thì được cấu thành từ nhiều dòng mã và nếu được viết theo kiểu cách mã spaghetti thì sẽ khó bảo trì.

Đây là một ví dụ khác về mã Spaghetti trong đó câu lệnh GOTO bị lạm dụng (ăn sâu vào logic của chương trình) và được dùng với các nhãn (label) có tên không rõ ràng. 

```
SCREEN 0
 INPUT "Bao nhiêu số để sắp xếp? "; T
 DIM n(T)
 FOR i = 1 TO T
 PRINT "SỐ THỨ:"; i
 INPUT n(i)
 NEXT i
 'Nhiều tính toán:
 C = T
E180:
 C = INT(C / 2)
 IF C = 0 THEN GOTO C330
 D = T - C
 E = 1
I220:
 f = E
F230:
 g = f + C
 SWAP n(f), n(g)
 f = f - C
 IF f > 0 THEN GOTO F230
 E = E + 1
 IF E > D THEN GOTO E180
GOTO I220
C330:
 PRINT "Liệt kê theo thứ tự là"
 FOR i = 1 TO T
 PRINT n(i)
 NEXT i

```

Xem thêm
--------

* Bóng bùn lớn (en), một phần mềm không có kiến trúc dễ nhận biết
* Cuộc so tài Viết mã C Khó đọc Quốc tế (en), một cuộc thi đấu để tạo ra mã C khó hiểu cho niềm vui thích
* Ngôn ngữ chỉ để viết (en), một ngôn ngữ có cú pháp kỳ quái đến nỗi mã kết quả sinh ra mang tính không thể lĩnh hội được
* Nợ kỹ thuật (en)

Tham khảo
---------

1. ↑  Markus, Pizka (2004). "Straightening spaghetti-code with refactoring?" (PDF). *Software Engineering Research and Practice*: 846–852. Bản gốc (PDF) lưu trữ ngày 5 tháng 3 năm 2018. Truy cập ngày 5 tháng 3 năm 2018.
2. ↑  Cram, David; Hedley, Paul (2005). "Pronouns and procedural meaning: The relevance of spaghetti code and paranoid delusion" (PDF). *Oxford University Working Papers in Linguistics, Philology and Phonetics*. **10**: 187–210. Bản gốc (PDF) lưu trữ ngày 6 tháng 3 năm 2018. Truy cập ngày 5 tháng 3 năm 2018.
3. ↑  Horstmann, Cay (2008). "Chapter 6 - Iteration". *Java Concepts for AP Computer Science* (bằng tiếng Anh) (ấn bản 5). Hoboken, NJ: J. Wiley & Sons. tr. 235–236. ISBN 978-0-470-18160-7. Truy cập ngày 2 tháng 1 năm 2017.
4. ↑  United States National Bureau of Standards (1980). *ASTM special technical publication*. United States Government Printing Office.
5. ↑  Moha, N.; Gueheneuc, Y. G.; Duchien, L.; Meur, A. F. Le (tháng 1 năm 2010). "DECOR: A Method for the Specification and Detection of Code and Design Smells". *IEEE Transactions on Software Engineering*. **36** (1): 20–36. CiteSeerX 10.1.1.156.1524. doi:10.1109/TSE.2009.50. ISSN 0098-5589.
6. ↑  Abbes, M.; Khomh, F.; Gueheneuc, Y. G.; Antoniol, G. (2011). *An Empirical Study of the Impact of Two Antipatterns, Blob and Spaghetti Code, on Program Comprehension*. *2011 15th European Conference on Software Maintenance and Reengineering*. tr. 181–190. CiteSeerX 10.1.1.294.1685. doi:10.1109/CSMR.2011.24. ISBN 978-1-61284-259-2.
7. ↑  Conway, Richard (1978). *A primer on disciplined programming using PL/I, PL/CS, and PL/CT*. Winthrop Publishers. ISBN 978-0-87626-712-7.
8. ↑  Conway, Richard; Gries, David (1979). *An Introduction to Programming* (ấn bản 3). Little, Brown. ISBN 978-0-316-15414-7.
9. ↑  Boehm, Barry W. (tháng 5 năm 1988). "A spiral model of software development and enhancement". *IEEE Computer*. **21** (2): 61–72. doi:10.1109/2.59.
10. ↑  Noll, Paul (1977). *Structured programming for the COBOL programmer: design, documentation, coding, testing*. M. Murach & Associates.
11. ↑  MTSBS[*cần giải thích*] (tháng 3-tháng 4 năm 1981). "BASICally speaking...FORTRAN bytes!!". *The Michigan Technic*. **99** (4). Kiểm tra giá trị ngày tháng trong: `|date=` (trợ giúp)Quản lý CS1: nhiều tên: danh sách tác giả (liên kết)
12. ↑  Troyer, O. De (ngày 13 tháng 5 năm 1991). *The OO-binary relationship model: A truly object oriented conceptual model*. *Advanced Information Systems Engineering*. Notes on Numerical Fluid Mechanics and Multidisciplinary Design (bằng tiếng Anh). **141**. tr. 561–578. doi:10.1007/3-540-54059-8\_104. ISBN 978-3-319-98176-5.
13. ↑  Tomov, Latchezar; Ivanova, Valentina (tháng 10 năm 2014). "Teaching Good Practices In Software Engineering by Counterexamples". *Computer Science and Education in Computer Science* (1): 397–405. Truy cập ngày 5 tháng 3 năm 2018.

Liên kết ngoài
--------------

* Go To Statement Considered Harmful. The classic repudiation of spaghetti code by 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 Lưu trữ 2018-07-16 tại Wayback Machine
* Refactoring Java spaghetti code into Java bento code separating out a bowl full of code from one class into seven classes
* Objects and Frameworks – Taking a Step Back by Brian Rinaldi
* Programming Pasta - Spaghetti, Lasagna, Ravioli and Macaroni Code
* Pasta Theory of Programming Lưu trữ 2018-06-12 tại Wayback Machine
* Spaghetti Code: Detangling Life and Work with Programmer Wisdom (English Edition)[*liên kết hỏng*]