コンピュータ・ソフトウェアを採用しているビジネスは、ソフトウェアを調達する力に強い制約を受ける。そしてソフトウェアを調達する力は、ソフトウェアの生存ルールに強く制約されている。
ソフトウェアの生存ルールというのは、役に立つプログラムであるための必須条件を指す。
この必須条件は複雑すぎるうえに、時の流れと状況によって変化するため精密には表現できない。
ひとつのオーソドックスな見方として
要求工学があり、50カテゴリを超える
非機能要件のリストを見れば、正気の沙汰でないことがすぐ分かるだろう。
機能要件に至ってはもはや「語り得ぬもの」のように見える。
これは「目的に沿っているかどうか」を指しているのだが、目的論哲学がまったく解けていないのと同じ理由で不可知のままでいる。おそらく目的という概念が、人間の因果関係の錯覚、とくに前後関係の取り違えを指しているからなのだと思う。
要求工学は成功を再現できる方法論を提供できていないものの、クリアしなければならないハードルは正しい。
システム受託開発の訴訟が目立ってきているのは、これらのうちの何かを満たしていないため「役に立たない」という不満が爆発したことによる。
部分的に満たせば良いのではなく、すべて満たす必要がある、という点は重要だ。
簡略化できる道筋があるならシステム開発訴訟は減りゆくだろうが、現実は逆行している。
受託開発の紛争を例に挙げているのは、許容できない損失の目安として定量化しうるからだ。
実際には自社開発のケースにも同じ制約が働いている。すべて満たして始めてスタートラインに乗るのであって、何かが欠ければ大きなダウンサイドがある。これはタレブの言う脆さのカテゴリに属している。
工学がさじを投げるとしても、僕は実務家としてアプローチを検証し続けなくてはならない。
開放系としてのデザイン
構成要素や環境が変わりゆく状況で、人が知覚できる構造を持つものといえば 散逸構造だ。
アナロジーとして川を考えると良い。方丈記は「行く川のながれは絶えずして、しかも本の水にあらず」から始まる。
川の必須条件として、水源や上流に雨が振り続けることと、下流に同量の水が流れ去ることが欠かせない。つまり、川は接続している外界のかたちに付随して維持できる存在である。
中国の故事には「刻舟求剣」もある。
舟から落とした剣を探すために、舟に目印を刻んでおいた、という話で、人の主観が変化をうまく記述できない様子を表している。
剣はまだ捜索の余地があるが、川じたいのデザインの難しさは治水の歴史に豊富な実例がある。
氾濫の被害が起きない程度に水量を維持したいという目的は、歴史の中で何度も不首尾に終わっている。近未来についてさえ、地球温暖化を考慮に入れると保証があるわけではない。
そもそも散逸構造はサステナブルではないという本質は重要だ。
入出力が絶えれば構造は失われ死滅する。
ソフトウェアの治水
温暖化により上流からの流入が増えたり途絶えたりするように、ソフトウェアも外界の変化を受ける。
たとえば、セキュリティの脆弱性は日々新たな攻撃手法が発見されているし、EUは創造力を発揮してGDPRのような法律を生み出し続けている。
接続している外界の変化に適応して修正を採り入れなければ、いずれ脆さが露呈し損失が生じる。
これは長い目で見た際のソフトウェアの主要な死因になる。対策は、できる限り頻繁に変更できる設計だろう。
もう一つの変化は、依存コンポーネントから来る。前提ライブラリ・ランタイム・外部サービス・OS・ハードウェアといった要素がある。
これらは自分で開発していないため外界と捉えたくなるのだが、一体化して動作するため内部の構成要素と捉えた方が適切に扱える。
それぞれの依存コンポーネントも外界の変化の影響を受けているため、時が経つにつれバージョンアップが発生する。
バージョンアップは一律に好ましいとは限らない。ライブラリには広い用途に適合するものが多くあり、時が経つにつれ重視する環境条件が乖離していくこともある。その場合、別の手段を探る必要が生まれる。
散逸構造は細部の無秩序な変更によって失われ得るため、けっきょくのところ依存しているライブラリなどが考えている計画や実装を理解しておくことは避けられない。
言い換えれば、ブラックボックスアプローチには制御できない脆さの発生源や増幅のリスクがつきまとう。この脆さに対処するには、自ら開発するという対策も有効である。近年広まっているヒューリスティックとは逆行する考えだろう。
システムテストの重要さ
長年にわたって開発を継続するにつれて、システムテストをより重視するようになり、ユニットテストを無価値に感じるようになってきたのだが、その理由はもう一つはっきりしなかった。一般的にもチェック範囲が広ければベターといった程度の認識だろう。
これまで述べてきたようにソフトウェアを開放系として再定義することで、システムテストの重要性がクリアになる。
ユニットテストは刻舟求剣なのだ。
ソフトウェアを利用する際の期待は一定の構造を維持し続けるが、それを構成する要素や利用環境はどんどん変わっていく。
よく知られているように開放系の挙動は、単に部分の挙動を足し合わせたものと異なる。
システムテストのコード資産こそが川の設計図であり、プロジェクトの本体とも言える。
ソフトウェアの脆さに対処する方法は、コードを変更するプロセスが主役であり、散逸構造を壊しうる変更を検出できなければ時の流れにつれて自壊する。
生体の冗長性を実装できないネック
頑健なソフトウェアの方法論をチェックしてみたが、相当ヘビーだ。その性質じたいがソフトウェアが脆い主要因なのかもしれない。
確率的に考えるなら、大多数のソフトウェアは時の流れによって死滅するよう定められているように見える。
ホメオスタシスのような維持機能は、複製の際のゆらぎと並列動作する要素の数の多さで頑健さを確保している。
ソフトウェアに限らず、工業製品は1つの製品内に重複する部品、それも各部品が似て非なる挙動をするような構造をとることができていない。
頻繁に変更するアプローチは、生体が持っている複製と除去のプロセスを単一のバージョンではなく、シリアルにバージョンアップする工程に採りいれる方法と言える。
ひとまず全体の制約条件を俯瞰的に考慮するとこのようなアプローチになる。
ソフトウェアの摩滅しない性質を考えれば、本来は悠久に生き永らえる余地もある。歴史の1ページに爪あとを残すといった瑣末な関わり方はほとんど無意味だろう。
しかし、遺跡から発掘される過去のプロダクトのうち現代に利用できる状態になっているものがない、という事実が大局的な限界を示しているようにも思う。