ソフトウェアは、当初想定していた寿命よりも長く使われ続ける傾向があります。5年の運用を見込んで作られたシステムが、10年以上稼働を続けることも珍しくありません。その間、誰も文書化しようとしなかった判断や場当たり的な対応が積み重なっていきます。こうした知識が失われるのは、開発を担った人たちがチームを去るときだけとは限りません。彼らがまだチームに在籍している間にも、静かに古くなっていくことがあるのです。ここでは、ある企業がこのギャップの代償の大きさを思い知った出来事を紹介します。
ある半導体機器メーカーが、優れたチップテスターを開発していました。これは、出荷前の半導体チップを検査するための装置で、高価かつ高性能な機器であり、自社のハードウェアの限界を突き詰めるように設計されていました。ハードウェアチームは開発サイクルを重ねるごとに、新たな機能を絶えず追加し続けていました。
やがて、ソフトウェアがそのペースについていけなくなりました。
ソフトウェアがボトルネックとなり、ハードウェアが本来発揮できるはずの能力を制限するようになったのです。そこで同社は、一見理にかなった判断を下しました。既存のソフトウェアを廃棄し、一から作り直すことにしたのです。
再構築には数百万ドルが投じられました。そして、失敗に終わりました。
新しいチームにコードを書く能力がなかったわけではありません。失敗の原因は、旧ソフトウェアの内部にどれほどの知識が蓄積されていたかを大きく見誤っていたことにあります。長年にわたって一つひとつ積み重ねられてきた詳細な設計判断と、試行錯誤の末に得られた知見の数々は、コード以外のどこにも記録されていませんでした。
その記録がなければ、新チームは旧バージョンと同等の機能を実現するためにどれほどの作業量が必要になるのか、見積もることすらできませんでした。
結局、同社は数百万ドルを失っただけで、置き換えようとしていたはずのソフトウェアの保守に逆戻りすることになったのです。
これは決して珍しい話ではありません。
長期間稼働してきたソフトウェアであれば、誰も書き留めてこなかった知識が積もり積もって、業界のどこでも起こり得る、ごくありふれた失敗のパターンだと言えるでしょう。
ソフトウェアは、想定よりずっと長生きする
多くのチームは、プロトタイプであれ、あるひとつの製品サイクルであれ、「いずれは置き換えられるだろう」というシステムであれ、短期的な視野で開発を進めます。ところが、実際には置き換えられないまま使われ続けます。
私たちは、ソフトウェアがどれほど長く使われ続けるかを、一貫して過小評価してしまう傾向があります。
5年の寿命を想定して作られたシステムが、その後さらに10年以上稼働することも珍しくありません。まるで、建設現場に置かれた仮設事務所が、本来の建物が完成してから20年経った今も、日々の業務に使われ続けているようなものです。
一方で、業界によっては、最初から長期的な視点で計画を立てるところもあります。
たとえば防衛産業のシステムは、およそ50年にわたって使用され続けることがあります。そこまで来ると、問題はソフトウェアだけにとどまりません。マザーボードをはじめとする物理的なハードウェア自体が製造中止となり、部品が手に入らない機器のために、ソフトウェアを保守し続けなければならないケースも出てきます。
これを、急成長中の若い企業が考える「長期」という感覚と比べてみてください。
急成長中のスタートアップにとって「長期」とは5年を意味するかもしれません。航空業界にとっては50年を意味するかもしれません。どちらもソフトウェアを開発しますが、その想定期間はまったく異なります。
このギャップが重要なのは、ドキュメント化に関する判断が、そのシステムが「実際にどれだけ使われ続けるか」ではなく、「今の時点でどれだけ使われそうに感じるか」に基づいて下されるからです。
チームがあるシステムを短命だと考えていれば、ドキュメント化を省略することは合理的な判断のように思えます。誰も、何十年も使われ続けるシステムを意図的に文書化せずに放置しようとしているわけではありません。ただ、初期の段階では、それがどれほど長く使われ続けることになるのか、誰も気づいていないだけなのです。
コードを書くことが、ドキュメント作成より優先されがちな理由
時間が限られている開発者に、次の機能を実装するのと、前の機能をドキュメント化するのと、どちらを優先するか尋ねれば、ほぼ間違いなく機能実装が選ばれます。これは決して怠慢のせいではありません。多くの場合、タイミングの問題です。
コードを書けば、その成果はすぐに得られます。一方でドキュメントは、いわば保険のようなもので、前もって手間というコストを払っておきながら、実際に必要になる日が来るまで、その価値を意識することはほとんどありません。そして、その日が来る頃には、往々にしてかなり時間が経っており、コードを書いた本人でさえ、なぜそのような判断を下したのか忘れてしまっています。
多くの人は、自分が書いたコードの内容を、書いてからわずか30分ほどで忘れてしまうと言われています。半年後に見返せば、まるで他人が書いたコードのように感じられることさえあります。
この効果が現れるまでの時間差こそが、ドキュメント作成よりコードの実装が優先されがちな理由です。チームがどれほど先を見据えて考え、目先の急ぎの対応に流されずにいられるかについては、これまで信頼できる形で計測されたことはありません。
書いた本人ですら、わからなくなるとき
この問題は、人がチームを去るときにだけ起こるリスクだと思われがちです。誰かが退職すれば、その人が持っていた知識も一緒に失われ、残されたチームがその穴を埋めようと奔走することになります。
しかし、この問題は、誰も退職していなくても、さらに厄介な形でも現れます。
私自身の研究の一環として、自分自身を対象にしたある示唆に富む実験を行いました。私は、あるコードベースの大部分を自ら書き、そのほとんどの変更内容をレビューしてきました。当然ながら、自分こそがそのシステムに関して、誰よりも精通した専門家だと考えていました。
学生の一人に、私の理解を試す質問をしてもらいました。その質問はこうでした。このシステムのある部分を切り出して、別の場所でも再利用できる形にするには、どれくらいの時間がかかると思いますか?
私は、自分がそのシステムの構造について知っていると信じている内容に基づいて、見積もりを答えました。
その後、システムの構成要素間の依存関係を詳しく調べたところ、私が頭の中で描いていた姿とはまったく異なる実態が明らかになりました。当初の見積もりは大きく外れており、私は見積もりを一から作り直さなければなりませんでした。
そのコードベースについて誰よりも詳しいはずだった私自身の頭の中の理解が、実際とは一致していなかったのです。しかもそれは、私が不注意だったからではありません。
これは、何年もかけて積み重ねられた判断の記憶が、たった一人の頭の中にしか存在しないときに起こることです。自分の住む街の地図が、道が少しずつ変わっていくうちに、誰にも知らされないまま、いつの間にか実態と合わなくなっていくのと同じことです。
その人がまだ自分の席に座っている間にも、誰かがチームを去るよりずっと前から、その理解はすでに間違ったものになっている可能性があるのです。
何を書き残すべきか
だからといって、すべてを文書化すべきだという話ではありません。コードの一行一行に「これは何をしているか」を説明するコメントが必要になっているとすれば、それは多くの場合、コード自体がもっとわかりやすく書かれるべきだというサインです。
優れたドキュメントは、コードが何をしているかの逐一の説明を省き、代わりになぜそうなっているかを記録します。その判断の背後にある前提条件、より単純な選択肢を除外した制約、そして、誰かがゼロからコードを読み解かなくても、その考え方を再現できるだけの理由づけです。
これこそが、記憶から真っ先に失われていく類の情報であり、新しく加わったメンバーが、どれほど注意深くコードを読んでも、推測のしようがない情報なのです。
同じことは、システムアーキテクチャにも当てはまります。
多くのチームは、システムの構造を説明する別ドキュメントを用意していますが、コードとそのドキュメントを一致させ続ける仕組みが何もない限り、両者はほぼ即座にずれ始めます。
ある開発者が、文書化された設計に沿って実装を進める中で、その設計が想定していなかったケースに直面し、納期に間に合わせるために設計から逸脱し、その説明を更新しないまま次の作業に移ってしまう、というようなことが起こります。
その瞬間から、アーキテクチャ図はただの飾りになります。増築を2回済ませ、壁を一つ取り壊した家に、誰も見なくなった昔の設計図が額装されて飾られているようなものです。
システムが実際にどう動いているかを正確に示す唯一の情報源はコードそのものであり、しかもそれは、その逸脱が起きた場に居合わせなかった人間が一目見ただけでは理解できないことがほとんどです。
設計と実装の整合性を保つには、人の努力に加えて自動化が必要
設計ドキュメントと実際のコードの整合性を、手作業だけで維持しようとするのはやめましょう。
代わりに機能するのは、実際のコードと意図されたアーキテクチャを継続的に比較する自動チェックです。これは、ソフトウェアが仕様どおりに動作しているかを自動テストが常に確認し続けるのと同じ考え方です。こうすることで、乖離が発生したその日のうちに検知でき、誰かが「その図が正しい」ことを必要とする日まで気づかれずに放置される事態を防げます。
ここには、文化的な側面も関わってきます。
ソフトウェアほど複雑なものを扱っていれば、ミスは避けられません。それをうまく乗り越えているチームでも、ミス自体は数多く起きています。
表面的な直接の原因の先にある「なぜそのミスが起きたのか」を問い続け、その答えをチーム全体で共有する習慣こそが、知識の継続性を築きます。個人の頭の中だけの教訓として終わらせないことが重要なのです。
これによって、苦労して得た知識が最初から一人の頭の中に閉じ込められてしまう事態を防ぐことができます。チップテスターの再開発チームを苦しめたのも、必要な知識が共有・継承されていなかったという、同じ問題でした。
選択肢が一つしかないとき
もし、稼働中のソフトウェアとそのドキュメントのどちらか一方しか残せないとしたら、残すべきはドキュメントです。
優れたドキュメントがあれば、必要になったときにソフトウェアをゼロから再構築できます。それは、皿を片付けた後でも、レシピさえあれば同じ料理をもう一度作れるのと同じことです。
ドキュメントのないソフトウェアからは、それについての実質的な理解は何も得られません。理解していないものを安全に変更することはできず、そうなるとそのソフトウェアは事実上使い物にならなくなります。担当が引き継がれる瞬間に行き詰まってしまいますが、どんなソフトウェアも、いずれは必ず引き継がれる時を迎えます。
最近、こんな主張を耳にすることが増えました。「担当が変わるときには、AIがソフトウェアをゼロから書き直せばよいのだから、ドキュメントやコードの読みやすさはもはやほとんど重要ではない」というものです。
これは誤りです。
この考え方が成り立つのは、ドキュメントが存在している場合に限られます。チップテスターの事例が示すとおり、ソフトウェアとはできあがったコードだけでなく、何年にもわたって一つひとつ積み重ねられてきた設計判断の集積でもあります。AIに再構築を任せるとしても、設計判断の背景を伝える情報は必要です。コードにもドキュメントにも残っていない判断の理由を、AIが確実に復元できるとは限りません。これは、チップテスターの再開発チームが直面した問題と共通しています。