設計と実装における「動的」


ソフトウェアの論理設計を考えるとき、よく機械や建築の設計図に喩えて説明されます(私も連載最初の方で使いました)。しかし、機械や建築物と性質的にまったく異なるのは、ソフトウェアは”動く”のです。そして、作った構造物(もしくは部品)はいつも同じ動きをするとは限らず、時間や環境などによって、まったく別の動きをすることもあるのです。

これって、実生活のモノにはとても喩えることができない特徴ではないでしょうか。

機械や建築と違うといえば違うのかもしれない.けれども,みんなだいすき " フレデリック・P・ブルックス・Jr"さんは近著「デザインのためのデザイン」で,建築を引き合いに出している.もしかしたら大した違いはないのかもしれない.

デザインのためのデザイン

デザインのためのデザイン

たぶん違いは,設計と実装の各フェーズについてそれぞれにある. むろん,実装を考えない設計なんてのはアリエナイし,設計を無視した実装も同様. 完全に分離するのは無理なのだけれども.それでも視点が大きく異なってくるので,一旦は分離する必要がある.

実装における「動的」

引用元は,"動く"と表現しているので,それに倣う.
機械は,そして建築は,動かないか? 否. 動かない機械なんてのは無いし,近代建築において,可動部のない建築は稀だろう.

ソフトウェアは,"動く"か? これは定義によって大きく異なる.マクロ物理的には動かないといって良いだろう.I/Oポートを介してアクチュエータを動かすことはあるだろうけれど,"動いて"いるのはアクチュエータであってソフトウェアではない.
プログラムカウンタ,各種レジスタ,メモリといった状態遷移はある.これをもって"動く"ということは,慣用的な表現だし,不自然はないだろう.

以上のように考えると,機械または建築と状態遷移に着目した場合のソフトウェアは,共に "動く".しかしこれらの間には違いがある.

機械または建築の可動部には,"遊び"があり,また他のマクロの物理条件の影響を受けやすい.人が普通に暮らせる範囲の温度や湿度で,ドアが開きづらくなったりする."完璧な歯車は回らない"というのは機構設計をするかたの基礎知識でもあろう.

一方,状態遷移に着目した場合のソフトウェアは,引用元の主張とは異なる特質を持つと私は考える.
「ソフトウェアの挙動には"遊び"が無く,ほぼ100%の再現性で動作する.」
割り込み禁止かつシングルスレッドの環境を一つ定めた時,下記コードは,確実に同じ動作を行う.
計測誤差を考慮する余地が無い.

 for(int i = 0; i < 100; i++) {
  printf("%d", i);
 }

現実のソフトウェアシステムでは,物理的な機構が絡まずにはいられない*1ので,"遊び"や誤差を考慮する必要があるのではあるが.

"遊び"が無いということは,言い換えると恐ろしいことになる.
実装が間違えていた場合に,"遊び"によって吸収されることなく,ダイレクトに誤った結果が出るということである.
この点 - ソフトウェアはむしろ定義した通りにしか動かない - が,実装としてのソフトウェアが持つ最も扱いづらい点であると私は考える.

また,ソフトウェアが静的な存在である一方で,外界の物理的存在が動的であることの齟齬が,ソフトウェアの実装を難しくしているとも考える.上記のコード片で例えるなら,割り込み禁止を解いた時点で,標準出力から得られる結果が常に再現されるかは怪しくなる.

設計における「動的」

こちらは私の専門外だし,上記の実装どころではないくらい多岐な視点を取り得るので,省略する.

引用元とは無関係に,ただ一つ指摘しておくならば,世の中でしばしば聞かれる「ソフトウェアの設計仕様はコロコロ変わるから建築より難しい」というのは,眉唾だと思っている.
建築方面の末端*2に携わっていた実父から,「貰った図面が古かったので現物合わせした」という話を何度も聞かされて,私は育った.

というわけで

動的とか静的とかって視点によって変わってしまう難しい概念なのですねー.

*1:例えばハードディスクはスピンドルが絡むし,UIがあれば人間が絡む

*2:正しく言うと,ビル空調などのエアダクトの板金職人