プログラミングが設計作業であるという話

いわゆる「ソフトウェア設計書」が設計ではなく、ソースコードが設計であるという話。
随筆です。考えマトメ中なので、ツッコミはそのあたり踏まえていただければ。

追記:ブコメに「設計の定義は?」とあったので末尾に追加しています。

追記(2024/8/15):設計書ってなんだろう?というのも書いておきました。
ソフトウェアの「設計書」とはなんなのか - きしだのHatena

このエントリで書いたのですけど、もうすこしちゃんと。
建築では多重下請けでやれてるのに業務システムでだめなのはなぜ? - きしだのHatena

このエントリでは次のように書いています。まあ、これで全てではあるのだけど。

「建築などの施工図面に相当するのはソースコードで、建築現場で多重下請けでやってる作業は、ソフトウェアだと(でも?)ビルドです」

あと「継続的デリバリーのソフトウェア工学」からの抜粋。

「継続的デリバリーのソフトウェア工学」では、「ソフトウェア開発を選んだ私たちがバカでない限り、私たちにとっての製造とは、ビルドボタンのクリックです」とあります

ところでほんと、売るために「継続的デリバリーの」をつけたことで売れなくなってるんじゃないかという気がするが、それは余談。

まあ、言いたいのは、ソフトウェア作成作業というのは、ハードウェア上で手続きを動かすことが最終成果であって、ソースコードや実行バイナリを作るのが目的ではないのですよ、ということ。
(「ソフトウェア作成というのは~」と書くと「いや、企業が利益を出すことが~」みたいなツッコミがたぶん来るので、「ソフトウェア作成作業」としてます)

10年前に「ソフトウェア工学は失敗している」と書いたときに思いのほか異論が出ていなかったのだけど、「継続的デリバリーのソフトウェア工学」でも「ソフトウェア工学は、重々しいくせにソフトウェア開発のプロセスに大した付加価値を与えてくれるわけではありませんでした」と書いてたり、やはりうまくいってなかった模様
ソフトウェア工学は失敗している - きしだのHatena

これは、ソフトウェア開発の目的を、暗に実行バイナリを作るところまでのようにとらえていたからじゃないかという気がします。2022年改訂の「ソフトウェア工学の基礎 改訂新版」でも、目次は次のようになっていて、一旦完成したあとの変更作業は「保守・進化」のように付加的な位置づけになっています。ソフトウェア工学の本の標準的な目次です。

第1章 ソフトウェアとソフトウェア工学
第2章 ソフトウェアプロセス
第3章 要求工学
第4章 モデル化技法とUML
第5章 データと制御の流れモデル
第6章 動的振舞いモデル
第7章 オブジェクト指向モデル
第8章 形式手法
第9章 設計技法
第10章 検証技術
第11章 ソフトウェアの保守・進化
第12章 開発環境とツール
第13章 安全・安心な社会のためのソフトウェア
第14章 プロジェクト管理

これは、受託開発やパッケージを想定して作られているともいえますが、ソフトウェアが比較的小規模で単純であったときには成り立っても、いまはもうあてはまりにくくなっています。

実際には、GitHubでプルリクをベースにCI / CDをまわして常時クラウドにデプロイしつつ、メトリクスをとり、負荷に合わせてサーバーを伸長縮退しながら動かし、コードを常に変更していくというのは、もはや開発作業の主要部分になっています。

要求工学やモデル化や設計技法が必要なフェーズはその「開発作業」の最初、むしろその開発作業に入る前に必要な事前作業ではないかという感じがします。

と書くと、「いや業務システムでは~」みたいなツッコミ入りそうですが、そこで決めるのは業務プロセスだったりして、ソフトウェアと密接ではあるものの、ソフトウェア一般の話ではなかったりもする。

まあ、ソフトウェア開発の技術というのは複雑さに立ち向かう技術でもあるので、業務プロセスの構築にも役に立つというか、業務プロセス構築とソフトウェア開発の区別はつきにくい、というのはさておき。

そして、CI/CDまわしてメトリクスとってといったことは、「ソフトウェア工学」ではあってもオマケ程度で、ほとんど触れられていません。

ともかくとして、先ほどサーバーを伸長縮退しながら動かすということを書いたけど、これも手作業でやっては間に合わないので設定なりなんなりコード化するわけですね。手続きの指定はもちろんコードで書きます。

そして、そういったコードは、書いてみるまでわからない、書くことでわかる、動かしてみてわかるということも多いです。

テスト駆動開発では、テストと共にコードを書くことで正しい設計に近づくということがコンセプトですが、テスト駆動ではないにしろ、コードを書かないことには正しい設計には近づかないのは確かではないかと。

そうすると、そういったコードそのものが設計であって、そのコードを書くプログラミングが設計作業なのではないかと思います。

-- -- ここからは追記 -- --
追記:ブコメにあって思い出したのだけど、設計という言葉には構造やアーキテクチャという意味と、その構造やアーキテクチャを事前に決めたものという意味があるのだけど、ここでは前者です。あと、よく言われるコーディングを伴わない事前作業としてのソフトウェア設計は、構造やアーキテクチャを決めきれておらず、その意味での「設計」になってないんじゃないかというのもありますね。大体は作ることを決める仕様決めの作業になってる。
つまりここでの「設計」は「どう作るか」「どのように作られているか」をあらわすもののはずで「何を作るか」ではなく、プログラムがどのように作られているか示すのはコードであるという感じですね。

追記:「設計書」もコードもどちらも設計では?っていうコメントあるけど、確かにその面もあって、「設計」ってコーディングの一部を表記変えてやってる面もある。クラス図とかはclassに変換可能で、なんならclassって書いたあと自動生成して「設計書で~す」ってやったりする。

追記:脱線ではあるけど、この文脈を作曲いいかえるとしても、「作曲は音源を作ることが最終成果で譜面を作るのが目的ではない、譜面は設計である」みたいになるように思います。実際、いまの音楽はほとんどが譜面記載できない音の塊で、演奏してナンボみたいなところがあると思います。
追記の追記:
音楽が商業にのるようになった時期は録音技術もなく楽譜を売ることが目的だったので、楽譜が最終成果だったわけですが、今どきの作曲は他者による再演は想定されてなく、ミックスまで含めた録音こそが最終成果になってますね。DTMでも。

追記: 建築でも現場でいろいろ変えるという指摘があるけど、柱の位置を変えたり増減するような構造部分の変更はせず、フィッティングの調整のような感じなんじゃないかと思います。その点では、コンパイル時の最適化に相当するんではないかと。コンパイラの自由度はかなりあって、コンパイラコンパイルオプションによって性能やバイナリサイズに差が出たりしますね。

追記(2024/8/15):ソースコードが設計であるという話は1992年にC++ Journalに載ったエッセイが古いものとしては有名です。
「コーディングは設計であり、テストとデバッグは設計の一部であり、私たちが通常ソフトウェア設計と呼ぶものもやはり設計の一部」
「設計ドキュメントをコードの前ではなく後に書くとはるかに正確なドキュメントが作成されるということを、全てのプログラマが知っています」
https://www.developerdotstar.com/mag/articles/reeves_design.html