---
title: "Спагетти-код"
type: "antipattern"
slug: "spaghetti-code"
url: "http://localhost:3000/ru/antipatterns/spaghetti-code.md"
description: "Исходный код программы с плохой структурой"
---
# Спагетти-код

> Исходный код программы с плохой структурой

**Спагетти-код** — это [компьютерный](https://en.wikipedia.org/wiki/Computer "Computer") [исходный код](https://en.wikipedia.org/wiki/Source%5Fcode "Source code"), в котором закодирован настолько запутанный [поток управления](https://en.wikipedia.org/wiki/Control%5Fflow "Control flow"), что его трудно понять. Управляющие операторы направляют [выполнение](https://en.wikipedia.org/wiki/Execution%5F%28computing%29 "Execution (computing)") [программы](https://en.wikipedia.org/wiki/Computer%5Fprogram "Computer program") так, что вместо качественной структуры он напоминает варёные [спагетти](https://en.wikipedia.org/wiki/Spaghetti "Spaghetti") — перекрученные и спутанные. Такой код, как правило, трудно [сопровождать](https://en.wikipedia.org/wiki/Software%5Fmaintenance "Software maintenance").

Поскольку логика потока управления, закодированная с помощью оператора [goto](https://en.wikipedia.org/wiki/Goto "Goto"), обычно ведёт к запутанному потоку управления, использование goto часто ассоциируется с отнесением кода к спагетти-коду. Практика [структурного программирования](https://en.wikipedia.org/wiki/Structured%5Fprogramming "Structured programming") была задумана для того, чтобы устранить необходимость в операторе goto и его применении как один из способов избежать появления спагетти-кода. Обеспечение создания высококачественного [программного обеспечения](https://en.wikipedia.org/wiki/Software "Software") вместо спагетти-кода часто связано с такими аспектами, как использование более удачных [инструментов](https://en.wikipedia.org/wiki/Software%5Ftool "Software tool"), [обучение](https://en.wikipedia.org/wiki/Training "Training") разработчиков и совершенствование [процессов разработки программного обеспечения](https://en.wikipedia.org/wiki/Software%5Fdevelopment%5Fprocess "Software development process").

Спагетти-код может также описывать [антипаттерн](https://en.wikipedia.org/wiki/Anti-pattern "Anti-pattern"), при котором [объектно-ориентированный код](https://en.wikipedia.org/wiki/Object-oriented%5Fprogramming "Object-oriented programming") пишется в процедурном стиле, например путём создания классов, методы которых чрезмерно длинны и неаккуратны, либо отказа от объектно-ориентированных концепций, таких как [полиморфизм](https://en.wikipedia.org/wiki/Polymorphism%5F%28computer%5Fscience%29 "Polymorphism (computer science)"). Наличие такой разновидности спагетти-кода может значительно снизить понятность системы.

## История

Неясно, когда был введён термин _спагетти-код_. Мартин Хопкинс одним из первых упомянул спагетти в этом контексте в 1972 году, написав, что «основная мотивация при отказе от оператора goto — это надежда, что получившиеся программы не будут выглядеть как тарелка спагетти». В книге 1978 года _A primer on disciplined programming using PL/I, PL/CS, and PL/CT_ [Ричард Конвей](https://en.wikipedia.org/wiki/Richard%5FW.%5FConway "Richard W. Conway") описывал программы, которые «имеют такую же чёткую логическую структуру, как тарелка спагетти», — эта фраза повторялась в книге 1979 года _An Introduction to Programming_, написанной им в соавторстве с [Дэвидом Грисом](https://en.wikipedia.org/wiki/David%5FGries "David Gries"). В статье 1988 года _A spiral model of software development and enhancement_ этот термин используется для описания более старой практики _модели «написал и исправил»_ (code and fix model), в которой не было планирования и которая в конечном итоге привела к разработке [каскадной модели](https://en.wikipedia.org/wiki/Waterfall%5Fmodel "Waterfall model"). В книге 1979 года _Structured programming for the COBOL programmer_ автор Пол Нолл использует выражения _спагетти-код_ и _крысиное гнездо_ как синонимы для описания плохо структурированного исходного кода.

На конференции _Ada – Europe '93_ язык [Ada](https://en.wikipedia.org/wiki/Ada%5F%28programming%5Flanguage%29 "Ada (programming language)") был охарактеризован как заставляющий программиста «создавать понятный код вместо спагетти-кода» благодаря его ограничивающему механизму распространения исключений.

В публикации [Национального бюро стандартов США](https://en.wikipedia.org/wiki/National%5FInstitute%5Fof%5FStandards%5Fand%5FTechnology "National Institute of Standards and Technology") 1980 года выражение _спагетти-программа_ использовалось для описания старых программ, имевших «фрагментированные и разбросанные файлы».

В пародии на компьютерные языки 1981 года в журнале _The Michigan Technic_ под названием «BASICally speaking...FORTRAN bytes!!» автор описывал [FORTRAN](https://en.wikipedia.org/wiki/FORTRAN "FORTRAN"), утверждая, что «он целиком состоит из спагетти-кода».

[Ричард Хэмминг](https://en.wikipedia.org/wiki/Richard%5FHamming "Richard Hamming") в своих лекциях описывал происхождение этого термина в контексте раннего программирования в двоичных кодах:

> Если при исправлении ошибки вы хотели вставить какие-то пропущенные инструкции, вы брали непосредственно предшествующую инструкцию и заменяли её переходом в какое-нибудь пустое место. Туда вы помещали инструкцию, которую только что перезаписали, добавляли инструкции, которые хотели вставить, а затем — переход обратно в основную программу. Таким образом, программа вскоре превращалась в последовательность переходов управления в странные места. Когда, как почти всегда случается, в исправлениях обнаруживались ошибки, вы снова применяли тот же приём, используя какое-нибудь другое доступное место. В результате _путь управления программы по памяти вскоре приобретал вид банки со спагетти._ Почему было не вставить их просто в ход инструкций? Потому что тогда пришлось бы пройти всю программу целиком и изменить все адреса, которые ссылались на какие-либо из перемещённых инструкций! Только не это!

## Примеры

### Простой

Следующий код на [BASIC](https://en.wikipedia.org/wiki/BASIC "BASIC") — программа, печатающая числа от 1 до 100, — относительно простой пример кода, который легче понять при структурированном потоке управления вместо использования goto. Использование `GOTO` для организации цикла и отсутствие отступов делают логику менее прозрачной.

1 i=0
2 i=i+1
3 PRINT i
4 IF i>=100 THEN GOTO 6
5 GOTO 2
6 END

Следующий код даёт тот же результат, но использует структурированный [оператор цикла](https://en.wikipedia.org/wiki/Loop%5F%28computing%29 "Loop (computing)") и отступы для улучшения читаемости.

1 FOR i=1 TO 100
2     PRINT i
3 NEXT i
4 END

### Более показательный

Следующий код реализует числовой [алгоритм сортировки](https://en.wikipedia.org/wiki/Sorting%5Falgorithm "Sorting algorithm"). Использование операторов goto придаёт потоку управления спагетти-подобный характер.

  INPUT "How many numbers should be sorted? "; T
  DIM n(T)
  FOR i = 1 TO T
    PRINT "NUMBER:"; i
    INPUT n(i)
  NEXT i
  'Вычисления:
  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
  IF n(f) > n(g) THEN 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 "The sorted list is"
  FOR i = 1 TO T
    PRINT n(i)
  NEXT i

## Связанные понятия

### Большой ком грязи

Большой ком грязи (big ball of mud) — это [программная система](https://en.wikipedia.org/wiki/Software%5Fsystem "Software system"), в которой отсутствует различимая архитектура. Хотя с точки зрения программной инженерии такие системы нежелательны, на практике они встречаются часто из-за коммерческого давления, [текучести кадров](https://en.wikipedia.org/wiki/Turnover%5F%28employment%29 "Turnover (employment)") разработчиков и [программной энтропии](https://en.wikipedia.org/wiki/Software%5Fentropy "Software entropy"). Термин был популяризирован Брайаном Футом и Джозефом Йодером, хотя они приписывают его авторство Брайану Марику.

> Большой ком грязи — это беспорядочно структурированные, расползающиеся, неряшливые, скреплённые скотчем и проволокой джунгли спагетти-кода. Такие системы несут на себе безошибочные следы неконтролируемого роста и многократного, наспех выполненного ремонта. Информация беспорядочно используется совместно отдалёнными элементами системы, нередко до такой степени, что почти вся важная информация становится глобальной или дублируется.
>
> Общая структура системы, возможно, никогда не была чётко определена.
>
> Если же она и была определена, она могла размыться до неузнаваемости. Программисты с хоть какой-то долей архитектурного чутья сторонятся этих трясин. Только те, кому архитектура безразлична и кому, возможно, комфортно мириться с инерцией каждодневной рутины латания дыр в этих рушащихся дамбах, готовы работать над такими системами.

— Брайан Фут и Джозеф Йодер, _Big Ball of Mud._ Fourth Conference on Patterns Languages of Programs (PLoP '97/EuroPLoP '97) Monticello, Illinois, September 1997

### Связанные с пастой

Вдохновлённые популярностью термина _спагетти-код_, появились и другие [пастообразные](https://en.wikipedia.org/wiki/Pasta "Pasta") термины, описывающие структурный характер кода:

Лазанья-код

Лазанья-код ([lasagna](https://en.wikipedia.org/wiki/Lasagna "Lasagna")) имеет [слои](https://en.wikipedia.org/wiki/Architectural%5Flayer "Architectural layer"), настолько переплетённые, что изменение в одном слое требует изменений и в других слоях.

Равиоли-код

Равиоли-код ([ravioli](https://en.wikipedia.org/wiki/Ravioli "Ravioli")) состоит из хорошо структурированных [классов](https://en.wikipedia.org/wiki/Class%5F%28programming%29 "Class (programming)"), которые легко понять по отдельности, но в сочетании они приводят к недостаточно ясному дизайну системы.
