スパゲティプログラム
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2023/11/04 02:40 UTC 版)
概要
命令型プログラミングでは、プログラムはコンピュータに対する手順書であり、プログラムに書かれた通りの順でコンピュータに対する指示(命令)が次々に出され、それをコンピュータが解釈することで動作していく。中間表現と仮想機械を利用する形態もあるが、最終的には機械語としてコンピュータが直接解釈可能な命令に変換される。メモリ上に存在する変数などによって管理されるプログラムの状態(ステート)を動的に変化させながら、プログラムに書かれた通りに文を次々に実行していく。基本的には上から下に辿る順でプログラム行が1文ずつ実行されていくが、行番号や何らかのラベルを指定して遠く離れた場所にジャンプする命令や、サブルーチン呼び出しと復帰など、遠く離れた場所にジャンプして別のコードを実行した後、また元の位置に戻る、といった命令もある。スパゲティプログラムというのは、規律のない不用意なジャンプの多用によって命令実行の順番が複雑に入り組んでいたり、プログラムの状態を管理するための変数が遠く離れた場所(プログラム全体のあちこち)で読み書きされていたりと、まさにスパゲティがこんがらがったような状態になったプログラムのことである。
スパゲティプログラムは、プログラムのテストを実施したり、内部動作解析やデバッグのためにプログラムをステップ実行によりトレース[注釈 1]したりすることが困難になる。結果として、プログラムのスムーズな開発や完成を妨げる。またソフトウェアを改良したり拡張したりすることも困難にする。
スパゲティプログラムは、特に1980年代頃[独自研究?]、まだ構造化プログラミングという知識・手法がプログラマたちに十分に普及しておらず、また仕様上構造化プログラミングが不可能なBASICのようなプログラミング言語が使われてしまっていた状況でしばしば発生した。
たとえ構造化プログラミングをサポートする現代的な環境であっても、変数名などが不適切で分かりづらいソースコード[注釈 2][注釈 3]や、複雑な条件分岐、あるいは処理内容および機能のまとまりに応じて適切に分割されていない長大なサブルーチンおよび巨大なクラスなどによって、可読性やメンテナンス性の欠如したスパゲティプログラムは容易に発生しうる。また後述するように、スレッドなどを使用した非同期プログラミングも、別の意味でのスパゲティ化を招きやすい。
ソースコードの可読性(読みやすさ)という概念は、読み手の技量や知識にも左右される相対的な指標であるため、初心者にとって難解なコードが必ずしもスパゲティプログラムとは言えない。しかし、むやみに技巧を凝らしたコードや、処理速度などの最適化のために可読性・汎用性・拡張性などを犠牲にしたコードは、一見では何をしたいのか理解できず、経験を積んだプログラマであっても内容の理解に時間を要したり誤解してしまったりすることがある。OSやAPI・ライブラリの不具合を回避するためにアプリケーションソフトウェア側で仕方なく必要とされるようなコードは、一見では無意味に思えるものもある。また、たとえ自分自身が書いたコードであっても、後から読み返すときには詳細を忘れてしまっていることも多い。そのようなとき、仕様書やソースコード中のコメントに十分な説明がなかったり、あるいはコードの修正によって仕様書やコメントが実装と乖離していたりすると、たちまち解読不能なスパゲティコードと化してしまう。
サブルーチンやクラスを最初に実装したときは、整然とした読みやすいコードになっていたとしても、機能追加や仕様変更に対応するためにコードを修正し、状態を管理・保持するための変数や条件分岐などが増えていくにつれて、徐々に読みやすさが失なわれ、設計も陳腐化していき、気付いたときにはスパゲティコードになっていることもある[2]。
現代では、プログラミング(コーディング)というものは、組織で業務として行う場合でも、たとえ個人的な趣味で行う場合でも、構造化プログラミングを行うべきだとされている。というのは、たとえ個人が自分ひとりのために書くプログラムでも、書いてから数ヶ月や数年もすれば、書いた時の記憶はほとんど、後から積み増しされた日々の記憶の山の中に埋もれてしまい、書いた当時に自分が何を考えて書いたか思い出せなくなり、まるで「赤の他人が書いたよう」に見える状態で読まなければならなくなるからである。日々多くの文字を読み多くの体験をしつづけている普通の人ならば、特にコードをしばしば書く人ならば、数ヶ月の間に大量のコードを読み書きすることになり、「数ヶ月前、数年前の自分」が書いたコードやそれを書いた時の理屈は、大量の記憶の中に埋もれてしまっており、すぐには思い出せず、「まるで他人が書いたコードのよう」で理解しがたいのである。だからプログラム(コード)というものは、チームで共同作業で書く場合でも、個人が個人的趣味で書く場合でも、誰が読んでも直感的に理解しやすいように、整然と、原則上から下へと素直に順番に実行されるように書くべきだとされている。またしっかりブロック化し、変数のスコープ(有効範囲)を常に意識し、たとえどんなに巨大なプログラムのどの行でも、もし変数の役割がやや不明な行があれば、せめてそのブロックの冒頭に戻れば変数の宣言も明確に書かれていて(さらにもし宣言だけでは変数の役割・機能が曖昧なら、その役割もコメント文などで明記されていて)、誰でも理解しやすいように(未来の「他人のような自分」でも理解できるように)、コードの中を何度も上下(右往左往)しなくても容易に変数の役割・機能も理解できるようにコードは書くべきだとされている。[独自研究?]
そういった、現代では当たり前になっている手法を実践できていないような、低品質なプログラムがスパゲティプログラムである。
スパゲティプログラムではないもの
単にプログラム規模に見合っていてソースファイルの数が多かったりバイナリ(実行ファイル)のサイズが相応に大きかったりするだけのプログラムや、リバースエンジニアリング防止のためにソースコード解析を意図的に困難にしたプログラムなどは、「スパゲティプログラム」には分類されない。
たとえば動的なウェブページの表示に必要とされるJavaScriptで書かれたプログラムの中には、コメントもなく、スペースや改行なしで変数名なども極端に短く、可読性を欠いたようなコードとなっているものもあるが、これはファイルのダウンロードおよびウェブブラウザによるスクリプト解釈の高速化を目的としたミニファイ(圧縮)処理や、ソースコードを解析しづらくする難読化を行うプログラミングツールによって自動生成されたコードであり、変換元のソースコードがそのようになっているわけではない。人間が読むことを目的としていない、自動生成されたコードをスパゲティコードと呼ぶことはない。
注釈
- ^ 1命令や1行だけを実行させ、命令ごとあるいは行ごとの状態が正常かどうかひとつひとつ確認すること。
- ^ 大規模プロジェクトでは命名規則がコーディング規約で整備されていることが多いが、その命名規則に従っていない一貫性のないコードは可読性の低いプログラムになりやすい。そもそも命名規則自体が現代的なコーディングスタイルに則しておらず不適切であることもある。
- ^ 1つの変数に複数の意味・役割を持たせて使いまわしすると、変数名も不適切・あいまいになりやすく、コードの可読性やメンテナンス性が低下する。
- ^ ただしCには大域ジャンプを可能とする
setjmp()
とlongjmp()
も用意されていた。 - ^ C++やObject Pascalにはデストラクタがあり、C#やJavaではusing文[4]やtry-finally文やtry-with-resources文[5]が使えるため、確実なリソース解放のためにgoto文やラベル付きbreak文などを使用する必要はない。
- ^ 「寝たバグを起こす」「寝ているバグを起こす」とも形容される。
出典
- ^ スパゲッティコード(スパゲッティプログラム)とは - 意味をわかりやすく - IT用語辞典 e-Words
- ^ スパゲッティコードの意味とは?具体例や対策について詳しく解説
- ^ ジャンプ ステートメント - break、continue、return、goto - C# | Microsoft Learn
- ^ using ステートメント - 破棄可能なオブジェクトが正しく使用されるようにする - C# | Microsoft Learn
- ^ try-with-resources 文 | Java SE 7 Documentation | Oracle
- ^ アンチパターンってなに? | Think IT(シンクイット)
- ^ 初期化 - cppreference.com
- ^ memcpy, memcpy_s - cppreference.com
- ^ How to: Define move constructors and move assignment operators (C++) | Microsoft Learn
- ^ Opinion -- 川俣 晶:ソフト開発を成功させる1つの方法 - @IT
- ^ Lecture 4: IPC & Threads / CSE 120: Principles of Operating Systems | Alex C. Snoeren, カリフォルニア大学サンディエゴ校
- ^ JEP 428: javaマルチスレッドプログラミングを容易にする構造化並行性
- ^ Windows with C++ - The Pursuit of Efficient and Composable Asynchronous Systems | Microsoft Learn
- ^ まずコードの可読性を最適化しよう | POSTD
- スパゲティプログラムのページへのリンク