ソフトウェア工学

ソフトウェア工学（ソフトウェアこうがく、英語: 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 の マネージコード などが多用されるようになった。 ソフトウェア工学はまだ若い分野であり、今も発展し続けている。最近のソフトウェア工学の重要な傾向を以下に示す。 アスペクト指向プログラミング ソースコードの様々な場所に定型的コードを追加・削除するツールを提供することで、品質を高める支援をする。アスペクトには、あらゆるオブジェクトや関数が特定の状況でどう振舞うべきかを記述している。例えば、アスペクトを使って、特定の型の全オブジェクトにデバッグ機能、ロギング機能、ロック機能などを追加できる。現在は、アスペクトを使って汎用コードを設計する方法の研究が進んでいる。関連する概念として、自動プログラミングやテンプレートがある。 アジャイルソフトウェア開発 目まぐるしく変化する市場に素早く対応できるソフトウェア開発の手法。この手法の信奉者は、従来型の文書を多用する手法は徐々に消えていくと信じている。関連する概念として、エクストリーム・プログラミングやリーンソフトウェア開発がある。 実証的ソフトウェア工学 ソフトウェア上で実験を行うことを重視する分野。実際の，もしくは実験的なソフトウェア開発作業やその開発履歴からデータを収集および分析し、そこから法則や理論を導き出そうとする。この手法の信奉者は、実用的な知見を得るためには、現実に存在するソフトウェアやその開発作業に対して手法を適用しその結果を評価することが必要であると考えている。 DevOps 開発 (Development) と運用 (Operations) を組み合わせたかばん語であり、開発担当者と運用担当者が連携して協力する（さらに両担当者の境目もあいまいにする）ソフトウェア開発の手法。ソフトウェアを迅速にビルドおよびテストする文化と環境により、確実なリリースを、以前よりも迅速に高い頻繁で可能とする組織体勢の構築を目指している。さらにDevOpsとセキュリティ（Security）を融合させるDevSecOpsに発展している。 モデル駆動工学 設計段階でテキストと図を使ったモデルを構築する。モデル変換やコード生成のツールを使って、モデルからコードの断片を抽出し、その後の開発に役立てる。 ソフトウェアプロダクトライン 一連のソフトウェア製品群を体系的に構築する手法。コードの再利用を発展させ、ソフトウェア開発工程を工業化しようとする試み。