ソフトウェア工学(ソフトウェアこうがく、英語: software engineering)はソフトウェアを対象とした工学である。すなわち、有用なソフトウェアが持つ特性・構造を探り、その構築・維持・管理に有用なプロセスを見出す学問である。

## 概要

ソフトウェア工学はソフトウェアの開発・運用・保守に関して体系的・定量的にその応用を考察する分野である。ソフトウェア工学は「工学」であり、ソフトウェアの信頼性・保守性・開発効率の向上などを目的とする。

ソフトウェア工学には、設計法と生産法の2領域がある。設計法はソフトウェア構造を扱う。ソフトウェア生産法はソフトウェアライフサイクルプロセスを扱う。これら二つの領域は利点と制約の面で相互関係がある。

ソフトウェア工学には、要求分析、ソフトウェア設計、プログラミング、ソフトウェアテスト、ソフトウェア保守といった作業に関する知識・ツール・手法が含まれる。ソフトウェア工学に関連する学問分野として、コンピュータ科学、コンピュータ工学、経営管理論、数学、プロジェクトマネジメント (ソフトウェアプロジェクト管理) 、品質管理、人間工学、システム工学がある。また、他分野とクロスオーバーしていたり、もしくはソフトウェア工学の1分野だったものが独立して別分野を形成したり(例:データベース設計)、別分野で培われた技術や概念がソフトウェア工学の対象となることもある(例:オブジェクト指向技術)。

software engineering という用語は Brian Randell (英語版)  が考案し、1968年の NATO ソフトウェア工学会議 で F.L. Bauer (英語版)  が使ったことで一般に広まった。

## 構造

人が臓器からなるように、ソフトウェアもコンポーネントからなる構造をもつ。この構造をソフトウェアアーキテクチャという。デザインパターン/アンチパターンはアーキテクチャより詳細度の高い構造である。またプログラミングの指針をプログラミングパラダイムという。パラダイムは結果として構造に影響を与える。例えば構造化プログラミング、オブジェクト指向プログラミングが挙げられる。

## ライフサイクル

ソフトウェアは生まれ、仕事をして、死ぬ。すなわち構想から廃止までの漸進的な発展、ライフサイクル(英語: life cycle)を持つ。ライフサイクルをプロセスとして認識したときによく見られるライフサイクルの型をライフサイクルモデル(英語: life cycle model)という。ライフサイクルを構成するプロセスはライフサイクルプロセス(英語: life cycle process)と呼ばれる。

例えばライフサイクルプロセスはしばしば「開発・運用・保守」に分けられ、そのうち開発プロセスはよく研究がなされている。開発プロセスモデルの例には、要求分析からテストまで順次1つずつおこなうウォーターフォール・モデル、開発期間を短く分け短期間に各開発工程を行いそれを繰り返すスパイラル・モデルが挙げられる。

ソフトウェアライフサイクルを定義する規格にはISO 12207がある。

## 方法論

ソフトウェアシステムをより良くする様々な方法論(英: methodology)がソフトウェア工学として研究されている。ライフサイクルごとの方法論や、アーキテクチャ実現に関する方法論などがある。特定の設計を採用しそれが開発プロセスと強くリンクするような方法論も当然存在する。オブジェクト指向開発方法論、ドメイン駆動設計がその例である。

### 設計方法論

ソフトウェアがより良い構造をもつための様々な方法論が研究されている。規格としてはUMLが挙げられる。

### 開発方法論

ソフトウェアライフサイクルプロセスの1つである開発プロセスをより良く進めるための方法論・その研究をソフトウェア開発方法論という。方法論(良くする方法)であり、典型的なパターンを見出しモデル化する分野とは区別される。

プロセスに着目した方法論には、ウォーターフォール・モデルに従うウォーターフォール開発、スパイラル・モデルに従う反復型開発、アジャイルソフトウェア開発などが挙げられる。 アジャイルソフトウェア開発のいくつかの開発手法(エクストリーム・プログラミングなど)では、例えばコーディング前に(あるいは同時に)テスト用のコードを書き、コーディングはそのテストに通過することを目標にして行う(テスト駆動開発、テストファースト)など、順序や各工程の意味づけを大きく変更している。ライフサイクル全体のマネジメント規格にはCMM/CMMI、ISO9001、ISO 12207、SLCP、IEEEソフトウェア規格、ファンクションポイント法、PMBOK、ISBOK、ISO/IEC9126などがある。

開発プロセスと運用プロセスの統合を目指す分野・方法論にはDevOpsがある。

## 主な研究分野

- ソフトウェア解析
- プログラム意味論
- ソフトウエア検証論
- ソフトウエア開発環境

## ソフトウェア工学の曖昧性と論争

ソフトウェア工学の典型的な定義として、以下のようなものがある。

- 「ソフトウェアの開発・運用・保守に体系的・学問的・定量的手法を応用する分野」
- 「ソフトウェア開発のあらゆる面を扱う工学分野」
- 「実際の機械上で機能する信頼性のあるソフトウェアを経済的に得るための確かな工学原則の確立と利用」

### ソフトウェア工学が工学であるかの議論

software engineering という英語の場合、必ずしも工学の一分野を指すわけではなく、以下のような用法もある。

- 元々、プログラミングおよびシステム分析と呼ばれていた活動などを総称的に software engineering と呼ぶ。
- プログラミングに必要とされる理論的側面をコンピュータ科学と呼び、そうでないあらゆる面を software engineering と称する。
- 「プログラミング」を単なる技巧や技能ではなく工学として扱うことを主張する用語であり、そのような指針を文書化したもので使われる。

software engineering は、ある種の学問的訓練、専門教育が必要であり、それにはソフトウェア開発には必ずしも使われないものも含まれるとする人もいる。よく言われる喩えとして、建築に携わる全ての人が建築学者ではないのと同様、ソースコードを書く人が常にソフトウェア工学者とは限らない。また、カナダの Professional Engineers Ontario という団体は、software engineering という呼称自体に反対している。すなわち、ソフトウェア開発は工学と呼ぶには未成熟で、それに携わる人々はプロのエンジニアとは呼べないという。

「ソフトウェア工学」を工学の一分野としてどう定義するかは、人によって異なり、論争が行われてきた。デイビッド・パーナスは、ソフトウェア工学は実際に工学の一形式であるとした。スティーブ・マコネルは工学ではないとしたが、工学へと進化すべきだと主張した。ドナルド・クヌースは、プログラミングは技であり科学だとした。エドガー・ダイクストラは、software engineering と software engineer という用語が特にアメリカ合衆国で誤用されていると指摘した。

#### ソフトウェア工学はコンピュータ科学であるかの議論

ソフトウェア工学が工学であるとした場合、ソフトウェア工学がコンピュータ科学の一分野であるか、という命題も長年の議論の対象となっている。

ソフトウェア工学はコンピュータ科学の一分野であると信じている者もいる。コンピュータ科学が数理論理学や計算複雑性理論などを含む計算全般を扱う学問であるのに対して、ソフトウェア工学はあくまで実用目的でコンピュータ処理を設計するものであり、異なる分野であると考えている者もいる。

ソフトウェア工学はコンピュータ科学でない、という意見の中には、科学か否か以前に、ソフトウェア工学はそもそも工学としての性質すら全く持っていないという考えさえある。

デイビッド・パーナスは「私はソフトウェア工学をコンピュータ科学の一分野としてではなく、土木工学、機械工学、化学工学、電気工学などなどの要素を組み合わせたものとして扱う」としている。

## 歴史

1949年のEDSACにおいて既に、ローダが初歩的なアセンブラの機能を備えていたことが知られる。1950年前後には、EDSACやEDVACといった初期のコンピュータにおけるプログラミングについて文献が公刊され、初歩的なプログラミング手法が知られるようになった。言語としては、直接バイナリで機械語を記述する煩雑さから、すぐにアセンブリ言語が生まれた。1950年代中ごろには Autocode、FORTRAN、LISPといった初期の高水準言語があらわれた。プログラミング言語の実用性を疑う向きも多かったことから、IBMが開発したFORTRANコンパイラは、初めての試みであるにもかかわらず、生成コードの最適化のために多大なコストが掛けられ、結果としてプログラミング言語の有効性を納得させた。

software crisis(日本語訳は「ソフトウェア危機」)というフレーズは、1968年に開催されたNATO Conference on Software Engineeringで現れたものとされている。

1970年代になると、UNIX、コードリポジトリ、make などの協調的ソフトウェアツールが登場する。1980年代、パーソナルコンピュータが登場し、急速に広まり、市販ソフトウェアも大量に販売されるようになっていった。Smalltalk-80が公開され、オブジェクト指向が新たなパラダイムとして徐々に注目されていった。1990年代になると、オブジェクト指向プログラミング、アジャイルソフトウェア開発、エクストリーム・プログラミングが徐々に主流になっていった。2000年代になると、Java、Ruby、Python、PHP といったインタプリタベースの言語や .NET Framework の マネージコード などが多用されるようになった。現代の一般的に認められているソフトウェアエンジニアリングのベストプラクティスは、ISO/IEC JTC 1/SC 7小委員会によって収集され、ソフトウェアエンジニアリング知識体系 (SWEBOK) として発行されています。 ソフトウェアエンジニアリングは、主要なコンピューティング分野の一つと見なされています。

## ソフトウェア工学の最近の傾向

ソフトウェア工学はまだ若い分野であり、今も発展し続けている。最近のソフトウェア工学の重要な傾向を以下に示す。