ソフトウェア工学
ソフトウェア工学（ソフトウェアこうがく、）は、コンピュータのプログラム、およびその作成行為であるプログラミングを対象とした工学である。
ソフトウェア工学はソフトウェアの開発・運用・保守に関して体系的・定量的にその応用を考察する分野である。
ソフトウェア工学には、設計法と生産法の二つに分類される領域がある。ソフトウェア設計法は、ソフトウェア構造を考察する領域であり、一般的にソフトウェア・アーキテクチャと呼称される。ソフトウェア生産法は、ソフトウェア開発工程を考察する領域であり、一般的にソフトウェア・プロセスと呼称される。これら二つの領域は利点と制約の面で相互関係がある。
ソフトウェア開発工程と呼ばれる技法や手順を含み、ソフトウェアの信頼性や保守性の向上を目的とする。具体的には、高度かつ安全なコンピュータのソフトウェアを短期間で設計するための研究などを行なう。
難易度の高いコード行数が数百万以上になる大規模ソフトウェアの開発に焦点を当てることが多い。
"software engineering" という用語は Brian Randell が考案し、1968年の NATO Software Engineering Conference で F.L. Bauer が使ったことで一般に広まった。
ソフトウェア工学には、要求分析、ソフトウェア設計、プログラミング、ソフトウェアテスト、ソフトウェア保守といった作業に関する知識・ツール・手法が含まれる。ソフトウェア工学に関連する学問分野として、コンピュータ科学、コンピュータ工学、経営管理論、数学、プロジェクトマネジメント (ソフトウェアプロジェクト管理) 、品質管理、人間工学、システム工学がある。
ソフトウェア工学では、通常、開発対象となるソフトウェアの開発を思いついた時点から、実際に動くソフトウェアが完成し、使用されるまでを、いくつかの工程に分けて考察する（ソフトウェア開発工程）。
これらの工程ごとに典型的な課題が存在し、課題に立ち向かう方法を明確にしようとする。
このため、ソフトウェア工学の対象は広範囲にわたる。
また、他分野とクロスオーバーしていたり、もしくはソフトウェア工学の1分野だったものが独立して別分野を形成したり（例：データベース設計）、別分野で培われた技術や概念がソフトウェア工学の対象となることもある（例：オブジェクト指向技術）。
ソフトウェア工学の典型的な定義として、以下のようなものがある。
"software engineering" という英語の場合、必ずしも工学の一分野を指すわけではなく、以下のような用法もある。
"software engineering" は、ある種の学問的訓練、専門教育が必要であり、それにはソフトウェア開発には必ずしも使われないものも含まれるとする人もいる。よく言われる喩えとして、建築に携わる全ての人が建築学者ではないのと同様、ソースコードを書く人が常にソフトウェア工学者とは限らない。また、カナダの Professional Engineers Ontario という団体は、"software engineering" という呼称自体に反対している。すなわち、ソフトウェア開発は工学と呼ぶには未成熟で、それに携わる人々はプロのエンジニアとは呼べないという。
「ソフトウェア工学」を工学の一分野としてどう定義するかは、人によって異なり、論争が行われてきた。デイビッド・パーナスは、ソフトウェア工学は実際に工学の一形式であるとした。スティーブ･マコネル は工学ではないとしたが、工学へと進化すべきだと主張した。ドナルド・クヌースは、プログラミングは技であり科学だとした。エドガー・ダイクストラは、"software engineering" と "software engineer" という用語が特にアメリカ合衆国で誤用されていると指摘した。
ソフトウェア工学が工学であるとした場合、ソフトウェア工学がコンピュータ科学の一分野であるか、という命題も長年の議論の対象となっている。
ソフトウェア工学はコンピュータ科学の一分野であると信じている者もいる。コンピュータ科学が数理論理学や計算複雑性理論などを含む計算全般を扱う学問であるのに対して、ソフトウェア工学はあくまで実用目的でコンピュータ処理を設計するものであり、異なる分野であると考えている者もいる。
ソフトウェア工学はコンピュータ科学でない、という意見の中には、科学か否か以前に、ソフトウェア工学はそもそも工学としての性質すら全く持っていないという考えさえある。
デイビッド・パーナスは「私はソフトウェア工学をコンピュータ科学の一分野としてではなく、土木工学、機械工学、化学工学、電気工学などなどの要素を組み合わせたものとして扱う」としている。
ソフトウェア工学の成果は、ソフトウェア開発方法論にまとめられることがある。
対象物をどのように人間が把握し、設計し、プログラムとして実現するかという視点からは、ソフトウェア開発方法論には次のような分類がある。開発プロジェクトをどのように運営するかに焦点を当てる場合は、特に「開発プロセスモデル」と呼び、以下の二種類に分類できる。ただし、以下の二種類は組み合わせて利用されることもある。
開発工程は、開発着手から終了まで次のように分けられることが多い。ただし用語や詳細な定義は開発方法論ごとにさまざまである。プロセスモデルにおいては、開発工程をどのように定義・配置するかが各モデルを規定する重要な要素となる。例えばウォーターフォール・モデルでは、要求分析からテスト-運用までを順に、1度ずつ行うことを想定している。スパイラル・モデルでは開発期間を短く分け、短期間に各開発工程を行い、それを繰り返す。
アジャイルソフトウェア開発のいくつかの開発手法（エクストリーム・プログラミングなど）では、例えばコーディング前に（あるいは同時に）テスト用のコードを書き、コーディングはそのテストに通過することを目標にして行う（テスト駆動開発、テストファースト）など、順序や各工程の意味づけを大きく変更している。
ソフトウェア開発の技術はプロダクト・プロセス・プロジェクト管理に分類できる。
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 の マネージコード などが多用されるようになった。
ソフトウェア工学はまだ若い分野であり、今も発展し続けている。最近のソフトウェア工学の重要な傾向を以下に示す。