mały|Nazwa nawiązuje do splątanych nitek spaghetti, gdzie prześledzenie przebiegu pojedynczej nitki makaronu jest trudne. Spaghetti code – w informatyce pejoratywny termin określający długi, skomplikowany i trudny do zrozumienia kod źródłowy programu ze względu na brak przejrzystego przepływu sterowania lub generalnej struktury procedur.
Jest to jeden z popularniejszych zapachów kodu, choć istnieją rzadkie przypadki, gdy obecność kodu spaghetti bywa usprawiedliwiona. Przykładem jest sytuacja, gdy kod spaghetti jest zawarty w przejrzystym i wyizolowanym interfejsie lub gdy tempo wdrożenia programu wymagało szybkiej implementacji.
Istnieją badania, wskazujące na to, że wyniki modeli przewidujących występowanie kodu spaghetti są zbliżone do wyników modeli przewidujących występowanie błędów w oprogramowaniu. Może to dowodzić możliwego związku między występowaniem kodu spaghetti a problemami z jakością oprogramowania.
Pojęcie kodu spaghetti znalazło zastosowanie jako analogia w językoznawstwie, a dokładniej w pragmatyce.
Symptomy i cechy Podstawowym symptomem, który świadczy o obecności kodu spaghetti jest utrudnione zrozumienie kodu przez innych programistów lub nawet samego autora kodu po upływie czasu. Czytanie takiego kodu może być czasochłonne.
W przypadku programowania obiektowego, charakterystyczna jest mała liczba obiektów, które posiadają obszerną implementację bez jednoznacznie określonej odpowiedzialności (złamanie zasady jednej odpowiedzialności). Obiekty mogą nie posiadać parametrów, a w zamian mogą wykorzystywać zmienne globalne. Taki kod z biegiem czasu nie okazuje się , wprowadzając powtórzenia kodu (wbrew zasadzie DRY). Powtarzające się fragmenty kodu mogą dodatkowo utrudniać jego utrzymanie, choć sama duplikacja kodu nie jest równoznaczna z kodem spaghetti.
Kod spaghetti może charakteryzować się stosowaniem podejścia proceduralnego w programach tworzonych w paradygmacie obiektowym.
Historia Kod spaghetti był charakterystyczny dla wczesnych języków proceduralnych, typu Fortran czy BASIC, popularnych jeszcze przed powstaniem metody programowania strukturalnego. Używano wtedy wielu instrukcji warunkowych, z zagnieżdżonymi wewnątrz konstrukcjami GOTO i wyjątków. Utrzymanie takiego kodu źródłowego było utrudnione ze względu na trudność w zrozumieniu głównej struktury przepływu sterowania kodu.
Programowanie strukturalne wprowadziło uporządkowanie w procesie tworzenia programów, dzięki dzieleniu zadania do wykonania na mniejsze podzadania, aż do uzyskania wystarczająco prostych do realizacji fragmentów (zgodnie z zasadą dziel i zwyciężaj). Ułatwiło to implementację w poszczególnych modułach procedur, które w całości dadzą pożądany efekt. We współczesnej praktyce zazwyczaj dzieli się program na funkcje, z których każda realizuje określony cel i może być wywoływana wielokrotnie.
W 1968 roku Edsger W. Dijkstra uznał, że instrukcje GOTO powinny zostać całkowicie zakazane w językach programowania wyższego poziomu, aby unikać powstawania kodu spaghetti. Dijkstra argumentował, że obecność instrukcji skoku komplikuje ludzkiemu czytelnikowi zadanie analizy i weryfikacji poprawności programu.
Przykład 10 INPUT count 20 LET steps = count 30 LET bbk = 0 40 LET bk = 1 50 IF count < 1 THEN GOTO 100 60 LET k = bbk + bk 70 LET bbk = bk 80 LET bk = k 90 LET count = count - 1 100 PRINT "Wyraz nr "; steps - count; "ciagu Fibonacciego wynosi: "; k 110 IF count > 0 THEN GOTO 50 120 END
Program wyświetla podaną przez użytkownika liczbę pierwszych wyrazów ciągu Fibonacciego. W kilku liniach trywialnego programu dwukrotnie użyto bezwarunkowej instrukcji skoku – GOTO. Przy bardziej złożonym kodzie i większej liczbie skoków pojawi się problem z jego zrozumieniem.
Ten sam cel zrealizowany przez programowanie strukturalne (w C): scanf ("%d",&steps); for (count = 0; count < steps; count++){ static int bbk = 0, bk = 1; int k = bbk + bk; bbk = bk; bk = k; printf ("Wyraz nr %d ciagu Fibonacciego wynosi: %d\n", count + 1,k); } Poszczególne kroki wykonywane są w przejrzystej i formalnej pętli. Ciąg instrukcji do wykonania w programowaniu strukturalnym nie może być dowolnie zmieniany, „przejścia” do poszczególnych bloków są obsługiwane przez zaimplementowane konstrukcje (np. for, while, do while czy if else).
Refaktoryzacja Jednym ze sposobów ograniczenia kodu spaghetti jest refaktoryzacja oparta na poszukiwaniu podobnych podzadań i wydzieleniu ich do dedykowanych modułów, funkcji lub metod. Takie działanie wymaga wydzielenia i stworzenia odpowiednich abstrakcji kodu.
Szczególnie użyteczne w zwalczaniu kodu spaghetti jest odpowiednie nazewnictwo obiektów oraz implementacja testów jednostkowych.
Przypisy
Kategoria:Kod źródłowy