스파게티 코드

스파게티 코드(spaghetti code)는 유지보수가 어렵고 구조화되지 않은 컴퓨터 소스 코드를 가리키는 경멸적인 표현이다. 구조가 좋지 않은 코드가 개발되는 원인은 변동성이 큰 프로젝트 요구사항, 프로그래밍 스타일 규칙의 부재, 능력이나 경험이 부족한 소프트웨어 엔지니어 등 여러 요인 때문일 수 있다.

 의미 
구조적 프로그래밍 구조 대신 GOTO 문을 남용하여 복잡하고 유지보수가 불가능한 프로그램을 만드는 코드를 흔히 스파게티 코드라고 한다. 이러한 코드는 복잡하고 얽힌 제어 구조를 가지고 있어서, 프로그램 흐름이 개념적으로 비틀리고 얽힌 스파게티 한 그릇과 같다.

1980년 미국 국립표준기술연구소의 간행물에서 스파게티 프로그램(spaghetti program)이라는 표현이 "조각나고 흩어진 파일"을 가진 오래된 프로그램을 묘사하는 데 사용되었다.

스파게티 코드는 객체 지향 코드가 절차적 스타일로 작성되는 안티패턴을 묘사하기도 한다. 예를 들어 메서드가 지나치게 길고 지저분한 클래스를 만들거나, 다형성과 같은 객체 지향 개념을 포기하는 경우이다. 이러한 형태의 스파게티 코드의 존재는 시스템의 이해도를 크게 떨어뜨릴 수 있다.

 역사 
스파게티 코드라는 표현이 언제부터 일반적으로 사용되기 시작했는지는 명확하지 않다. 그러나 1972년에 마틴 홉킨스가 "goto 문을 제거하는 주된 동기는 결과 프로그램이 스파게티 한 그릇처럼 보이지 않을 것이라는 희망이다"라고 언급한 것을 포함하여 언급된 바 있다.Hopkins, M. E. (1972): A Case fo the GOTO. In: ACM '72: Proceedings of the ACM annual conference - Volume 2, August 1972, pp 787–790, p 59 DOI:https://dl.acm.org/doi/10.1145/800194.805860 1978년 《PL/I, PL/CS, PL/CT를 사용한 훈련된 프로그래밍에 대한 입문서》(A primer on disciplined programming using PL/I, PL/CS, and PL/CT)라는 책에서 리처드 콘웨이는 "스파게티 한 접시와 같은 깨끗한 논리적 구조"를 가진 프로그램들을 묘사했으며, 이 표현은 그가 데이비드 그리스와 공저한 1979년 《프로그래밍 입문》(An Introduction to Programming)에서 반복되었다. 1988년 《소프트웨어 개발 및 향상의 나선형 모델》(A spiral model of software development and enhancement) 논문에서는 계획이 부족하고 결국 폭포수 모델의 개발로 이어진 코드 앤 픽스 모델의 오래된 관행을 설명하는 데 이 용어가 사용되었다. 1979년 《COBOL 프로그래머를 위한 구조화된 프로그래밍》(Structured programming for the COBOL programmer)에서 저자 폴 놀은 구조화되지 않은 소스 코드를 묘사하기 위해 스파게티 코드와 쥐둥지를 동의어로 사용했다.

에이다 - 유럽 '93(Ada – Europe '93) 컨퍼런스에서 에이다는 제한적인 예외 전파 메커니즘 때문에 프로그래머로 하여금 "스파게티 코드 대신 이해 가능한 코드를 생산하도록" 강제한다고 묘사되었다.

1981년 《미시간 테크닉》(The Michigan Technic)에 실린 "BASICally speaking...FORTRAN bytes!!"라는 제목의 컴퓨터 언어 패러디에서 저자는 FORTRAN에 대해 "전적으로 스파게티 코드로 구성되어 있다"고 묘사했다.

리처드 해밍은 그의 강의에서 이진 코드로 초기 프로그래밍을 하던 맥락에서 이 용어의 어원을 다음과 같이 설명했다.오류를 수정할 때 빠뜨린 명령어를 삽입하려면 바로 앞의 명령어를 가져와서 빈 공간으로의 전송으로 바꾸었다. 거기에 방금 덮어쓴 명령어를 넣고, 삽입하려는 명령어들을 추가한 다음, 메인 프로그램으로 돌아가는 전송을 따라갔다. 따라서 프로그램은 곧 이상한 곳으로의 제어 점프 순서가 되었다. 거의 항상 발생하는 것처럼 수정에 오류가 있을 때는 다른 사용 가능한 공간을 사용하여 같은 기법을 다시 사용했다. 결과적으로 저장소를 통한 프로그램의 제어 경로는 곧 스파게티 통과 같은 모습을 띠게 되었다. 명령어 실행 중에 간단히 삽입하지 않는 이유는 무엇인가? 그렇게 하면 전체 프로그램을 검토하고 이동된 명령어를 참조하는 모든 주소를 변경해야 하기 때문이다! 그런 일은 절대 하지 않겠다!

 관련 표현 

 라비올리 코드 
라비올리 코드는 객체 지향 프로그래밍에 특정한 용어이다. 개별적으로는 이해하기 쉬운 잘 구조화된 클래스들로 구성되어 있지만 전체적으로는 이해하기 어려운 코드를 묘사한다.

 라자냐 코드 
라자냐 코드는 계층이 너무 복잡하고 얽혀 있어서 한 계층의 변경이 다른 모든 계층의 변경을 필요로 하는 코드를 가리킨다.

 예제 

다음은 베이직에서 스파게티 코드의 간단한 예시로 간주될 수 있는 것이다. 이 프로그램은 1부터 100까지의 각 숫자와 그 제곱을 화면에 출력한다. 코드가 수행하는 다양한 동작을 구분하기 위해 들여쓰기가 사용되지 않았으며, 프로그램의 GOTO 문은 행 번호에 대한 의존성을 만든다. 한 영역에서 다른 영역으로의 실행 흐름을 예측하기가 더 어렵다. 실제 스파게티 코드의 발생은 더 복잡하며 프로그램의 유지보수 비용을 크게 증가시킬 수 있다.1 i=0
2 i=i+1
3 PRINT i;"squared=";i*i
4 IF i>=100 THEN GOTO 6
5 GOTO 2
6 PRINT "Program Completed."
7 END다음은 구조적 프로그래밍 스타일로 작성된 동일한 코드이다.1 FOR i=1 TO 100
2     PRINT i;"squared=";i*i
3 NEXT i
4 PRINT "Program Completed."
5 END프로그램은 한 영역에서 다른 영역으로 점프하지만, for 루프와 함수가 흐름 제어를 제공하는 반면 goto 문은 자의적인 흐름 제어를 조장하기 때문에, 이러한 점프는 형식적이고 더 쉽게 예측할 수 있다. 이 예시는 작지만, 실제 세계의 프로그램들은 많은 코드 행으로 구성되어 있으며 스파게티 코드 방식으로 작성될 때 유지보수가 어렵다.

다음은 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
  'Calculations:
  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

 같이 보기 
 IOCCC, 보기 좋게 모호한 C 코드를 만드는 대회
 기술 부채

 각주 

 외부 링크 
 Go To Statement Considered Harmful. 에츠허르 데이크스트라의 스파게티 코드에 대한 고전적인 반박
 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 
 자바 스파게티 코드를 자바 벤토 코드로 리팩터링하기 한 클래스에서 한 그릇 가득한 코드를 일곱 개의 클래스로 분리하기
 Objects and Frameworks – Taking a Step Back - 브라이언 리날디
 Programming Pasta - Spaghetti, Lasagna, Ravioli and Macaroni Code 
 프로그래밍의 파스타 이론

분류:정보기술 용어
분류:멸칭
분류:안티패턴
분류:소프트웨어 공학
분류:스파게티에 대한 비유