震源地は忘れてしまったのですが、「(IT)エンジニアならばソフトウェア工学を知っておいて欲しい」という X のポストだったと思います。ソフトウェア開発するならば、工学的なアプローチも知っておかないといけないのは当然で、まあ、当たり前だよね…と思っていたのですが、意外と「これは、ソフトウェア工学の本だろう」というのが出て来なかったので、備忘録的に書いておきます。
最初に「工学」の定義なのですが、属人性が低く再現性があり量産が可能であることとします。これは、ソフトウェアに限らず、建築、造船、車両技術などを見ればわかる通り、
- 工場で誰もが(一定技術は必要かもしれないが)製品を作れる
- 設計図などがあり同じ製品を作ることができる(これも技術が必要だが)
- 単一でなく、複数のものが作れる
ということです。いわゆる「プロダクト」というやつですね。ただし、IT プロジェクトのように一回性の高いものがあり、プロダクトとプロジェクトを区別することもあるのですが、ひとつ視点を高くして「IT プロジェクトを成功に導く手法あるいは確率的に成功させる方法」として、IT プロジェクトを生産するための「プロダクト」手法というメタ的な考え方ができます。
たとえば、ビルを建築する場合には、それなりの手順があります。基礎を作る、鉄骨を入れるための場所を決めるなどの手順を踏まないとビルは建設できません。もちろん、適当にやってもビルの建築はできるかもしれませんが、確率的にそのビルは崩壊してしまうかもしれません。それよりも、確実に建築できる方法をとるわけです。これがサグラダファミリアも同じで、時間は掛かりましたが(途中ちょっと間違っていたらしいので)、最終的に建築できるものを建築しているという手順や基礎固めがあります。
この手順はソフトウェア開発や運用においても存在します。開発手法として、ウォーターフォール開発やアジャイル開発、スパイラル開発などさまざまな開発手法が提案されて、最近では AI によるバイブコーディングも含まれます。しかし、それらを越えたところに、いわゆる基礎固めとして「ソフトウェア開発プロジェクトを成功させる」ための基礎知識なり知識の蓄積があります。これがソフトウェア工学です。基礎固めなのですから、基礎知識がないとプロジェクトの成功は危うくなります。そういうもので、欠かすことができない要素ということになります。

プログラム言語の本が入っていないのは、ソフトウェア工学自体には特定のプログラム言語は必須条件ではないからです。正確には、プログラム言語という概念が必要になるので、「コンパイラ」の本が必要なのですが、残念ながら私は持っていません。これに適当なコンパイラの本が追加されます。
プロジェクト知識体系 PMBOK(第6版以前)
私自身は PMBOK はあまり好きではないのですが、知識体系として網羅性が高いのでソフトウェア開発に有用です。特に、プロジェクト計画、コミュニケーション、文書管理、調達などの分類がわかりやすいです。ただし、第8版以降は、それぞれのプロセスの実施よりも全体のコンセプトに移行してしまっているので、あまり役に立ちません。アジャイル開発スクラムや CCPM と整合性を合わせたために変な感じになっています。どうせならば、がちがちにプロセス重視でやったほうが PMBOK の有用性は高いです。
PMBOK では全体の要素を網羅するのが目的ですから、それぞれのプロセス/知識分野をすべて同じ力で関わる必要はありません。全体として摘まんでいけばいいんです。ですが、PMP 取得のプロジェクトマネージャがでてくると、PMP の通りにやるのでこれが問題だったのです。最近の PMBOK 系の PM はどうなんでしょうね?
先に書いた通り、PMBOK はアジャイル開発を含むようになっているので、PMBOK(かつてはウォーターフォール開発)とアジャイル開発(スクラム、XP、チケット駆動など)を離反させる必要はありません。全体としてソフトウェア開発のプロジェクトマネジメントという視点で捉えることができます。
UML
設計書を細かく文章で書くことも必要ではありますが、手書き UML だけでも十分なことが多いです。アジャイル開発にしても、開発意図などを伝えるときに UML を使う方がスムースでしょう。いわゆる、建築の三面図や、工作物の図面にあたるものです。
UML は多種にわたっていますが、PMBOK と同様に必要なものとしてつまんでおけば ok です。少なくとも UML を全く知らない、まったく使わない、状態でなければ ok ということです。
私が良く使っているのは、
- クラス図
- シーケンス図
- ステートチャート(状態遷移図)
- オブジェクト図(整合性をあわせるために)
- ユースケース記述
の5種類です。たしか、アジャイル本にも書いたと思いますが、クラス図、シーケンス図、ステートチャート、オブジェクト図は、時間と具象・抽象の2軸で4象限を網羅できます。ユースケース記述は、システムテストに有効なのと、要件定義や検収に有用なためです。
計算機プログラムの構造と解釈
この本は中身が LISP なので読みにくいので、実際はヘネパタ本を使ってください。ヘネパタ本は kindle 版しか手元になかったので、代わりの登場です。パターソン&ヘネシーの「コンピュータの構造と設計」ですね。
コンピュータの内部構造(CPU、主記憶装置、入力装置、出力装置、補助記憶装置)とレジスタ周りが解説されていれば ok です。論理回路はあってもなくてもいいです。これは論理式で代用ができます。
コンピュータがきっちりと電子と電子回路、バス等で繋がっていること知っておくことは重要です。例えば、CPU と主記憶装置は分離しているので、なんらかのキャッシュが発生します、とかレジスタがありますとかいう話です。補助記憶装置は、HDD、SSD、DVD、データベース などの媒体があり、それぞれスピードが違うのでソフトウェア開発をするときに注意が必要なときがあります、とか。WEB 開発にしても回線のスピードがあるし、データはパケットで送られるから衝突や損失もあるとか。そのあたりが想像できるようになります。
逆に、このあたりのコンピューターの弱点がないものとして「設計」をしてしまうとえらいことになります。当然、要件定義(とくに非機能要件)に関わってくる話です。
ソフトウェア・テストの技法
ソフトウェア開発で、一番ソフトウェア工学らしいのが「テスト技法」の分野です。プログラマ的には TDD(テスト駆動)とかを思い浮かべていますが、いわゆる旧来のテスターや品質管理部門の人達がいる分野です。QA の人たちですね。
このあたり、計測がしやすいので、カバレッジとかコードの複雑度の計測とかいろいろな製品があります。はっきり言って、プログラマから見ると邪魔な存在ですが、必要不可欠な人たちです。テスト駆動の再帰テストはコードが崩れないことを保証するものですが、製品として完成していること=要件定義などを満たすこと、は保証してくれません。単に動くとか、バグがないとかいうのだけでは駄目で、なんらかの「保証」が必要なんですよね。
これは、自動車の品質管理や安全基準を思い浮かべるとわかります。自動車は動くことは大切ですが、何かにぶつかったり事故が起こったときに人が生き残ることが重要です。これが安全性です。なので、人型に衝突させたり、ボンネットに重たい玉を落としたりします(いわゆる、人間の頭や体ですね)。こういう風な極限状態でも車が安全であることを実験で保証するわけですが、果たして、ソフトウェア開発において極限状態の保証はどうやってやるのでしょうか? ということです。
つまりは「テスト技法」には、自動車で言う処の極限状態や頻度は低いが重大な障害が発生するところを、工学的に網羅していくという分野です。見知ったところでは、境界値テストとか、負荷テストとか、極限状態のテストです。
ソフトウェア開発の定量化手法
「ファンクションポイント法」を読むと、今更な感じもあり、現在のプログラム言語やライブラリに沿っていないので、あまり意味がない感じがします。実際そうです。そのまま使うことはできません。ここに書いてあるのは、機能単位、コード量などから、プロジェクト計画時に見積もりをしようという発想があります。これが重要な要素になります。
開発プロジェクトが「いつまで終わるのか?」というのは重要な要素です。当然、人件費がかかるので「いくら掛かるのか?」が出てきます。つまりは、計画と予算がプロジェクトの開始時に必要なわけです。官庁の見積もりでもそうですが、事前にスケジュールと予算が必要になります。でも、実際作ってみないとわからないですよね。でも、走り出す前に計画と予算を出さないといけないのです。実に矛盾しているように見えるのですが、これは建築や土木、車両の分野でも同じです。事前に見積もりを出します。
ビル建築の場合は、部材ごとに見積もりを出して合算していきます。それぞれの工法には施工期間が事前にわかっているのでこれで期間を見積もれます。途中に天候の問題などがありますが、それは余裕を持っているのであまりずれることはありません。まあ、沖縄の普天間基地の移転のように岩盤の調査をミスったりするとずれてしまうわけですが(それが意図的であるかどうかは別として)
ソフトウェア開発は複雑度が高いので、正確な見積もりは出しにくい。というのがソフトウェア開発におけるマネージャ、プログラマの意見ですが、だからといって目途を全く立てないという訳ではありません。実は、そこそこのプログラマはいつごろまでプログラムができるかを、的確に予想してコーディングすることができます。おそらく、経験と勘なのですが、なんらかの形で「定量化」することができます(実際は、PSP(ソフトウェア・パーソナル・プロセス)を使って測定できます。しかし、しんどいので私はあまりやりたくありません)。
つまりは、何かを基準にして(それが経験と勘であったとしても)何らかの法則で計算することによって、プロジェクトが計画可能であることを示すのが、定量化手法のベースです。逆にいえば、何かの基準を持たない人(新人や、コーディングをしないマネージャなど)は計画を立てることができません。このあたりの弊害は「BIG THINGS」に書いてあります。
ソフトウェア開発見積りガイドブック
定量化手法は、規模見積の話(いわゆるスケジュール)になりますが、この本では予算の話になります。ベースは定量化と同じようにファンクションポイント法などを使って計算をしていきます。
いままでは、プロジェクトの期間は、人月を掛けることによって予算に直結していたのですが、最近は異なります。高度なライブラリを使ったり、これからは AI エージェントを利用したりと、期間とは異なった形でプロジェクト予算が変わってきます。つまりは、建築でいうところの部材調達の比率が大きくなるということです。クラウドの利用料や特定の UI システムの利用、SAP や Microsoft 365 などの継続利用料というものが関わってきます。
つまりは、同じ要件定義でもなにかのライブラリを使うとか使わないとか、クラウドを使うとか使わないとかの形で、開発費用や運用費用が異なるということです。これらの状況はガイドブックができた頃にはなかった話なのですが、意味合いとしては昔からありました。
そのように必要な人件費とプロジェクトが活用する設備費用を合算していきます。当然、運用時の費用も計算します。これは PMBOK にあるのですが、定量化や金額見積もりの具体的な方法については、この2冊が非常に詳しいです。内容は古いのですが。
コンパイラ
写真にはでてきませんが、「コンパイラ」について挙げておきます。プログラムコードがそのままコンピュータで実行されるわけではないこと、その前にコンパイル作業が必須であることを理解できるようになります。
プログラムコードの文法、字句解析、文法解析、中間言語、マシン語への変換、などの流れを知っておくと、プログラムのコードがどう動くか?だけではなく、どのように最適化されるのか、なぜそのような文法になっているのかを知ることができます。これは、プログラム言語に関係ありません。中間言語で動く Java や C#、スクリプト言語として動く Python や JavaScript など(正確にはプリコンパイルなどの機能がありますが)の内部の動きを把握することで、単なる抽象概念としてのプログラム言語ではなくて、具体的な制限のあるプログラム言語を知ることができ限界値がどこにあるのかを気にするようになります。
たとえば、いろいろなソートアルゴリズムがありますが、それがなぜ「いろいろ」なのかということです。抽象的なメモリ配置ではなくて、具体的なメモリ(架空ではない)をアクセスしているので「いろいろ」になるのです。その感覚を養うために「コンパイラ」のざっとした知識が必要になります。
大学時代に読んでいた「コンパイラ」はこれですね。著者は aho だったのか。
おまけ。こっちのコンパイラも。
