プログラミングは「設計」である - モジログ を読んで、元機械系エンジニアの感想というかなんというか。

とりあえず重箱の隅っぽいけど補足

ここで「誰が作っても同じ」というのはもちろん、作る人に一定のスキルがあるというのが前提で、また「同じ」といっても、許容しうる程度の違いはあるものとする。

たぶん建築でもそうだと思うけど、図面には寸法公差とゆーのがあって `許容しうる程度の違い` が明確になってる。「ここの長さは 100mm」じゃなくて「ここの長さは 99.80mm〜100.20mm」みたいに。公差というのは文字通りその範囲に収めろという意味なので、日本語訳+書いてない部分も補足すると「(`作る人に一定のスキル` があろうが無かろうが )`同じ` にしろ」ということになる。

機械の開発とソフトウェアの開発を比べると

儂の知ってる機械の(広義の)開発から製品として販売するまでのプロセスは大雑把に言うと以下のようなもの。

  1. 企画: どういうものを作るのか大雑把に決める
  2. (狭義の)開発: どういうものを作るのか詳細に決める
  3. 製造: 2.で決められた通りのものをたくさん作る
  4. 販売: お客さんのお金と作ったモノを交換する

2.開発 の「詳細に」というのは機械の場合だと寸法に始まって、材質、加工方法、表面処理、組立方法(締め付けトルクとか)なんかと、機能部品ならどういう条件で動かしたときにどの値は X±n の範囲内とかそんなこと*1
それらはどうやって決めるかっていうと

  • シミュレーション
  • 試作品作成->テスト

のいずれかで上限でも下限でも問題無いことを確認して決める。
つまり 2.開発 の成果物である図面*2というのは「この通りのモノを作れば要求されてる機能・性能を満足しますよ」というもので、その中で許容してる `揺れ` は機能・性能的に問題無い範囲であることを保証*3するもの。

じゃあ機械の設計図に相当するモノはソフトウェア開発でいうと何なのか?って話になる。

そこから先は、誰が作っても同じものができる」レベルとは、一体どのあたりだろうか。

`モジュールやクラスを決めるくらい`じゃ全然足りない(この辺は機械だと 1. 企画 の段階で決まると思う)。`関数やメソッドのインターフェイスを決めるくらい`というのは「インターフェース」を誤解してなければ*4どういう条件でその関数/メソッドはどういう挙動をするのかは定まらないのでまだ足りない。自分の知ってる範囲だと一番近いのは TDD/BDD のテストか、ソースコードそのもの。
http://japanese.joelonsoftware.com/PainlessSpecs/2.html に書いてあるような仕様書ならそれで良いように思うが、実際問題そんなにきちんとした仕様書というのは絵に描いた餅なんだろうなという感じがする(現実の仕様書がどういうモノなのかは知らない)。
もしちゃんとした(誰が書こうがその仕様書に書かれている仕様を満足していれば機能・性能的にも満足するような)仕様書が存在してるならその仕様書を作るまで、そうでないなら(最終的に機能・性能的に満足することが確かになる)ユニットテストソースコードを作るまで、が

それはまさに、建築家やグラフィック・デザイナー、ファッション・デザイナーなどが、ああでもない、こうでもない、というトライ&エラーを繰り返しながらデザイン=設計を作り上げていく、それと同じような作業。

であり

いくら多くの人間や時間、労力を投入したとしても、それはソフトウェアの品質と何の関係もなく、100人の凡人が束になっても、1人の専門家のスキル・知識にかなわない。「誰が作っても同じものができる」にはほど遠く、むしろ「誰が作るかでぜんぜん違う」世界なのだ。

となるんじゃないかと思う。
余談だけど図面読むのは(素人でも何となくわかるけど)多少知識が必要なとこもあって、図面読めるようになるのは高級なプログラミング言語を読めるようになるのと大差ないんじゃないかな。人によるかも。だから何だという訳でもない。


ソフトウェアの開発は、機械の開発とも建築とも違うとこがある。

まずトライ&エラーの容易さ。ソフトウェアはこれ以上容易に試すことができる分野って思いつかないくらい容易なはず。機械は試作品作るのにそれなりに時間も金もかかるけどまだ試すこともできる。建築なんて滅多にトライするわけにもいかない。ロケットとかになると現実的にはできないんじゃなかろーか。つまりこの観点ではソフトウェア開発は建設よりも機械の開発に近い。
建築とかが施工の前に完全に設計をするのは、机上の設計で機能・性能を満足できるかどうか判断できるノウハウがそれなりにあるというのもあるだろうけど、ほとんどトライ&エラーに頼れないというのもあるんじゃないかと思う。
機械の開発だとトライ&エラーで決める部分がかなりある。儂のいたとこは大きく開発陣が「設計屋」と「テスト屋」に分かれてて、「設計屋」は図面上やシミュレーションでわかる範囲の仕様を決める、「テスト屋」は残った部分をトライ&エラー繰り返しながら決める、という感じだった。ちょうどソフトウェアの α1公開->bug fix->α2公開->bug fix->以下ループ みたいに。


それと区切られてる分野の広さというか何と言うか*5。IT業界でも SI とか web とか組み込みとか色々分かれてはいるのだろうけど、それでもまだ範囲が(機械や建築に比べると)はるかに広いような。
感覚的には "web プログラミング" というのは "乗り物の開発" くらい広い。乗り物って一言で言っても自動車とか飛行機とか新幹線とか自転車とかエレベーターとかあって、それぞれに満足すべき機能・性能も違うし必要になる技術も違う。さらに自動車でもエンジンなのかシャーシなのか内装なのかデザイン(見た目)なのかでやることは全然違って、それぞれに専門家がいる。
建築家に関してはよく知らないけど、トイレもキッチンも階段も外装も全部同じ人がやってるような気がするので、ソフトウェア開発は機械の開発より建築に近いんでないかと思う。けど、住宅を設計する建築家と高層ビルを設計する建築家は全然別なのではないかとも思う。
技術の方はプログラミングの技術って他の分野でも応用が利くとこが広い+勉強しやすいんでいいことにしても、要求される機能・性能の違いはタイヘンなんじゃなかろーか。というのは要求される機能・性能がある程度固定されてると、それを満足するのに必要な大枠の設計ってある程度決められるというか定石みたいなもんがあって、だから企画の段階である程度までは決められる。そこを手探りでやってる分時間(=コスト)かかるのと、手探りで決めた大枠の上に諸々積み上げてって問題が起きたときに大枠の部分はおかしくないだろうと思えるのと、怪しいかもと思っちゃうのはけっこーな差なのではなかろうか、と。

*1:全部が図面に書かれてるわけじゃない=別の文書に書かれるものも含めてるけど、これらは開発の段階で決定するので

*2:と付属する諸々の文書

*3:プログラマのいう「保証されてる」ほどの確かさではないけど

*4:関数/メソッドの名前と引数/戻り値の型を指定するものと理解してるけど、ほとんどさわったこと無いので自信なし。

*5:IT業界のことはよく知らんのでデタラメかも