複雑性はなぜ破綻するのか?
計算量と認知負荷から読み解く、ソフトウェアの限界について考えました。
これは、情報過多時代の「過学習」にも通じるテーマです。
私たちの脳がどこで飽和し、どこから理解が追いつかなくなるのか..その構造を知ることは、エンジニアリングだけでなくリスキリングの土台にもなりうると思っています。
はじめに
ソフトウェア開発には、「複雑性が問題を生む」 という常識があります。
- なぜ複雑になると破綻するのか
- どこから複雑と呼べるのか
- どの瞬間に人の理解が追いつかなくなるのか
- 技術負債は、なぜ突然「手がつけられない」段階まで膨張するのか
ソフトウェアの複雑性を・・
という3つのレンズで読み解いてみました。
ポイントは、「複雑なコード」 ではなく、「複雑さ自体の本質」 を扱うことです。
1. 複雑性とは「計算量の爆発」を人間が受け止められなくなる現象
ソフトウェアの複雑性は、しばしば計算量の爆発として語られます。
-
O(N)→ まだ追える -
O(N²)→ 何が起きているか曖昧になる -
O(2^N)→ もはや理解不能
しかし、これは人間の脳にもまったく同じことが起きます。
人間の作業記憶は 7±2 個 しか保持できないとされます1。これは心理学の古典的研究ですが、エンジニアにとっては「認知の計算量制限」を意味します。
※その後の研究では、実効容量は 4±1 個程度という見解も有力です(Cowan 2001 など)
つまり、コード設計が
O(理解) を超えた瞬間、人は壊れます。
人間の作業記憶は「5〜9チャンク程度しか同時に扱えない」とされており2、複雑な設計はすぐにこの上限にぶつかります。
2. "設計の計算量"はコード行数ではなく、「関係性の数」で決まる
複雑性は、コード量では決まりません。関係性(依存・制約・フロー)の数で決まります。
たとえば
- A が B を知っていて
- B が C を参照していて
- C が非同期に A を更新する
これを理解するには、人間は A-B-C-A の閉路を追跡しなければなりません。
これは脳にとって DFS(深さ優先探索) のような負荷です。
関係性が増えるほど、理解の計算量は指数的に増える。
コードは線形に増えるが、理解コストは指数関数的に増える。
だから設計は突然破綻します。崩壊は徐々には進みません。ある閾値を超えた瞬間、いきなり崩れます。まるで「臨界点」を超えた化学反応のようです。
依存関係の数が増えると、開発スピードより先に「依存の管理コスト」が爆発していきます3.
3. 認知負荷は "見えない" 技術負債である
複雑性が破綻するのは、技術の問題ではなく、人間が処理できる情報量の限界を超えるためです。
認知負荷が高い設計には、次の兆候があります。
- 一度読んでも理解できない
- 仕様とコードの対応が不明
- "ここを変えるとどこに影響する?" が見えない
- レビューが摩耗する
- バグが"点"ではなく"面"で発生する
これらはすべて、「計算量過多」「キャパシティ超過」の症状です。
技術負債とは、
"認知負荷が金利として積もっていく現象"
と捉えるべきです。
技術負債は、単なる「後回しの修正」ではなく、開発者の頭の中に積み上がる認知負荷そのものです4。
4. アーキテクチャの本質は「計算量の制御」
設計とは、格好いい図を描くことではありません。
本質はただ一つです。
"理解に必要な計算量を O(1) に近づけること"
そのためにアーキテクチャが存在します。
- 層で区切る → 認知対象を一定に保つ
- 責務を限定する → 計算経路を短くする
- 境界を作る → 関係性を切断する
- API を設計する → 認知を抽象化する
きれいな設計にも理由があります。それは美しいからではなく、
脳への負荷を最小化するためです。
“Cognitive complexity coding metrics assess code based on its readability and self-explainability.”
5. 「複雑性の破綻ライン」は、個人ではなく"チーム"に依存する
認知負荷は人によって異なります。
- 初心者はすぐ
O(爆発) - ベテランは
O(ある程度耐える) - 設計者は
O(ノイズを抽象化できる)
つまり複雑性の破綻ラインはチーム固有のものであり、汎用的な"正しさ"では語れません。
技術は移植できても、認知限界は移植できない。
あるプロジェクトでうまくいった設計が、別のチームでは壊滅する理由はここにあります。
6. 実務で「複雑性の爆発」を防ぐ方法
実務で効く、複雑性制御の原則をまとめます。
① 関係性を減らす(依存を切る)
- イベント駆動で発散した依存を整理する
- 双方向参照を禁止する
- "A は B を知らない世界"を設計する
短い例
UI → UseCase → Repository だけにし、UI が Repository を直接呼ばないようにする。
② 読み方を O(1) に近づける
- コードが"初見で"理解できる必要があります
- 初回で理解できない設計は複雑すぎます
短い例
「この関数は何をするか?」が 1画面以内で完結する ようにする。
③ ドキュメントではなく「構造」で説明する
- ドキュメントで補強が必要な設計は、すでに
O(1)ではありません
短い例
「ここは〇〇層です」と説明不要なように、フォルダと責務を一致させる。
④ レビューで"認知負荷"を観測する
- レビューの摩耗は、構造の疲労です
短い例
PR に「ここ分かりづらい」コメントが連発したら、設計の構造疲労を疑う。
⑤ チームの認知限界を把握する
- ベテランの限界ではなく
- チームの最低ラインで設計すべきです
短い例
「新人でも追える構造」を基準にし、ベテラン依存の暗黙知を排除する。
おわりに
複雑性の問題は、理論では説明できますが、実務ではほとんど語られません。しかし、ソフトウェアが破綻するのはいつだって、「人間が理解できなくなったとき」 です。
ソフトウェアの限界は、計算資源ではなく、人間の認知資源で決まります。
この視点が定着すると、設計やレビューやアーキテクチャの見え方が変わります。
複雑性を避けるのではなく、複雑性と"共存できる形"を探す ことが大切です。
-
“humans can effectively process no more than seven units, or chunks, of information, plus or minus two.”
George A. Miller, The Magical Number Seven, Plus or Minus Two(Britannica 解説より)
https://www.britannica.com/topic/The-Magical-Number-Seven-Plus-or-Minus-Two-Some-Limits-on-Our-Capacity-for-Processing-Information ↩ -
“Working memory can typically process 5–9 pieces, or chunks, of information at any given time.”
Cognitive Load Theory quick guide, Medical College of Wisconsin
https://www.mcw.edu/-/media/MCW/Education/Academic-Affairs/OEI/Faculty-Quick-Guides/Cognitive-Load-Theory.pdf ↩ -
“As we scale and increase parallel deliveries, the exponential growth of dependencies can become overwhelming.”
Slow Product Development? Dependencies are the Cause
https://blog.zeroblockers.com/p/slow-product-development-dependencies-are-the-cause ↩ -
“Complex code, linguistic anti-patterns, code smells, and other things we collectively lump under ‘technical debt’ all increase cognitive load.”
Cognitive load – Unconscious Agile
https://unconsciousagile.com/2024/01/28/cognitive-load.html ↩
