本質的な複雑性と偶有的な複雑性の区別は、有名な『銀の弾丸はない』で提唱されたものだ。
本質的な複雑性というのは、「どうあがいても、その問題に内包されている複雑性」のことで、たとえば医療で言ったら「麻薬施用免許を持たない医師やスタッフが麻薬処方の指示を出してはいけない」というのはあたりまえの話だけど「じゃあその処方箋はどう現場で管理されないといけないんですか」とか「鍵付きのところに保存されてないとダメで、そこから取り出すためには麻薬施用免許を持った医師が出して、麻薬施用免許を持った医師がハンコを押した処方箋がないといけない、そしてそれは参照できるところに管理されていなければならない」みたいな話はまあ、医療安全上の本質的複雑性だと言っていいだろう。
一方で偶有的な複雑性というのは、実装方法だとか、技術的な制限だとか、あるいは間違えた解決領域を作ってしまったことだとかによる複雑性だ。たとえば、システムがバッチで一度にデータを処理する機能を作っていないせいで、ユーザーが一件一件目grepしながら正しいデータを登録しなければいけない手間だとか、まあそういうやつ。
一般的に、本質的な複雑性に向き合いましょう。そのためには、偶有的な複雑性を減らしていきましょう。というのが、「模範解答」だと思う。
しかし、世の中ってのはそんなに簡単ではなくて、すくなくともひとつの問題がここに絡んでくる。それは、「本質的」というものは本質的に主観的(と言ってしまうのが言い過ぎであれば、間主観的)なものである、ということ。
この世の中に、ア・プリオリに本質的なものは存在しない。というか、そもそも「問題」すらア・プリオリには存在しない。だれかがなにかを「問題視」して初めてそこに問題が生まれる、という考え方にぼくはたつ。さて、問題領域がそうやって生まれたときに、そこに対する「本質」ってのもまた、「誰かがこの視座から見たら本質的に見える」というように判断することではじめて「本質性」というのが立ち上がってくる。「問題の本質」は問題に内在しておらず、その問題に対峙する人間の観察に存在する。それが「本質」というのは本質的に主観的である、ということの意味だ。異なる主観をぶつけ合い、磨き合い、間主観性の中で生まれる「本質」もあるだろうけれど、それは議論に参加しているひとたちの間主観に存在するもので、やはり問題に対してア・プリオリに存在するわけではない。
つまり、「本質性」というのは、だれがその問題に対峙するかによって容易に変化するものである、と言える。
ところで、ぼくたちがなにかサービスやソフトウェアを作っているとする。このとき、前述した通り「本質的な複雑性に向き合いましょう。そのためには、偶有的な複雑性を減らしていきましょう」というのが「模範解答」であろう。このお題目は大変に必要だし、何が本質的な複雑性で何が偶有的な複雑性なのかを仮説でいいから切り分けて、「筋の良さそうな切り分け」を目指すのは大事だ。つまり、「いまそれを作っているひとたちにとっての間主観性で削り出した本質的複雑性と偶有的複雑性の区別」があるのとないでは、全然問題解決の筋のよさが違うということはあたりまえにおこる。
仮説でいいからこのふたつの区別をやらないと、「いまの業務が持っている偶有的複雑性を維持するためだけの要らない機能を作りまくってそれがその後の足枷になる」みたいなことが平気で起こる。本質的な複雑性を偶有的複雑性だと読み間違えて、「実際はそこの細かい仕様が満たされていないと業務上重要な担保したいことがみたせねえんだよ!!!」みたいなことが平気で起こる。だから、がんばってこのふたつを切り分けようとするのはたいへん大事。
しかし、である。ここでさらにややこしいことに、「よし、切り分けて、偶有的複雑性を排除して、本質的複雑性に向き合ったぞ!!!」とおもって、ユーザーにサービスを使ってもらうと、ま〜〜〜あびっくりするくらいにわれわれは本質的複雑性と偶有的複雑性を見誤っていたことに気づいたりする。いくら頭のなかでやっててもそれは想像でしかなくて、実際に動くブツで、実際に動く業務をやってみないことには、われわれのサービスがなにをどれくらい実際に解決できて、どんな偶有的複雑性を持ち込んでしまったのかが、わからない。これはべつにわれわれが無能なだけじゃなくて、やはり「ないものでないことをやってても気づけない」んだ。それは「あるものである業務を実際にやったときに初めてユーザーさんが気付けるような、実戦で使われ、初めて形が見えてくるもの」なんだよな。
つまり、本質的複雑性というのは「実際にユーザーが実際のものを使った時に、ユーザーや我々の間主観性の中に立ち現れてくるもの」であり、ア・プリオリに存在するものではないわけだ。
だから、ふたつのことが言えて、ひとつは、なにが本質的な複雑性でありなにが偶有的な複雑性であるかは自明ではないので、みんなで知恵を絞って仮説としてたててサービスをつくらないといけない、ということ。この仮説の精度は大事。そして、仮説の精度がいくらよくても、だれかの頭のなかにある本質的複雑性ではない、「本物の本質的複雑性」は現実の運用の中でからしか見出されないので、実際に存在するものを使ってもらうことでしかわからない、ということ。
「本質的複雑性だとおもって向き合ったところが、どっちかっていうと偶有的複雑性でした」(あるいはその逆)に対して、そうして得られた学びをシステムにフィードバックし、直していければ、チームの筋肉が育っていくし、サービスは常に新しい「本質的複雑性に向かい、偶有的複雑性を減らす」ための新しいやり方に向かっていける。一方、学ぶことはできたけど、それだけではコードはなにも変わっていない場合、システムの現状と「学習されたはずの本質的複雑性と偶有的複雑性の分離」はどんどん乖離していく。これは本来の意味での「技術的負債」というやつだし、「ドメインの蒸留」という言葉が指しているのも、ここでの学びをソフトウェアの設計に再投資していけ、という話のはずだ。
というわけで、ぼくは日々、本番で使われているサービスこそが最も学びの多い場であり、最も負債が貯まる場所だと思っている。これはいいことなのだ。学習の機会なのだから。そしてこの学びをもって、粛々とこの負債を解決していきたい(=新しい学びにマッチする構造にソフトウェアを変えていく)。さらには、新しく見えてきた「現場のここを解くことで現場が抱えた偶有的複雑性を肩代わりして、現場が本質に向き合える!」といういわゆる新機能を同時に作り上げていくことだって貪欲にやっていきたい(それはまた新しい学び/倒すべき負債を産むことになる。世界をよくする永久機関が完成しちまったなぁ〜!!)。と、最近はこいう夢をもって日々を過ごしている。それだけの夢を説明するのに、これだけの背景を説明しているのは、ひとことで言ってしまえる夢のそのバックグランドを知って欲しかったから。
「課題を解決して飯をくう」をやっているひとたち、一緒に、こういう夢をもって日々を過ごしていきましょう