「卵が先か、鶏が先か」という言い方があります。
卵がなければ鶏は生まれない。しかし、鶏がいなければ卵は産まれない。一見すると、原因と結果が循環しているように見えるため、昔から答えの出ない問いのように扱われてきました。
ただ、この問いは単なる言葉遊びではないと思っています。ここには、物事をどう切り分けて理解するのか、という本質的な問題が含まれています。
この記事の視点
「どちらが先か」という問いは、最初から独立していた二つのものを比べているように見えます。しかし実際には、一体の現象を人間が分けた後に、順序や主従の問いが事後的に生まれている場合があります。設計で重要なのは、順序を決めることではなく、分けたもの同士の依存関係を見ることです。
最初から卵と鶏が分かれていたわけではない
生物の進化を考えると、最初から「卵」と「鶏」が明確に分かれて存在していたわけではありません。
そこにあったのは、連続した生命の変化です。ある生物がいて、その子孫が少しずつ変化し、さらにその子孫が変化していく。その長い連続の中で、後から見れば「ここから鶏と呼べる」と判断できる地点があります。
しかし、その境界は自然界に太い線として引かれているわけではありません。人間が分類し、名前を与え、理解するために線を引いています。
つまり、「卵が先か、鶏が先か」という問いは、すでに「卵」と「鶏」を別々のものとして切り分けた後に生まれる問いです。
最初から卵と鶏が別々に存在していたのではありません。連続した生命の流れを、人間が理解するために分けた結果、「どちらが先か」という問いが生まれました。
ここで起きているのは、時間的に連続したものを後から区切ることです。言い換えれば、卵と鶏の問題は、通時的な切断の問題です。
ハードウェアとソフトウェアは、別の型の問題である
似た問いは、コンピューターにもあります。
「ハードウェアが先か、ソフトウェアが先か」という問いです。
物理的に見れば、ハードウェアが先に見えます。CPU、メモリ、ストレージ、NIC、電源、バスがなければ、ソフトウェアは実行できません。ソフトウェアは、何らかの実行基盤があって初めて動きます。この意味では、ハードウェアがソフトウェアを可能にしています。
しかし、ハードウェアだけを見ても、それが何のための装置なのかは分かりません。
CPU は命令を実行する装置であり、メモリはデータを保持する装置であり、NIC は通信を処理する装置です。こうした意味づけは、ソフトウェア的な抽象や計算モデルによって与えられています。
ハードウェアはソフトウェアを可能にします。一方で、ソフトウェアはハードウェアに意味を与えます。
これは、卵と鶏のように、時間の流れを後から切断する問題とは少し違います。ハードウェアとソフトウェアは、同時に存在する二つの側面が、互いに可能性と意味を与え合っています。
つまり、ハードウェアとソフトウェアの問題は、共時的な相互構成の問題です。
同じ仕組みではなく、共通する構造を見ている
ここで注意しなければならないのは、卵と鶏、ハードウェアとソフトウェア、抽象と具体が、すべて同じメカニズムで成り立っているわけではないという点です。
| 対象 | 問題の型 | 何が起きているか |
|---|---|---|
| 卵と鶏 | 通時的な切断 | 連続した時間変化を後から区切ることで境界が問題になる |
| ハードウェアとソフトウェア | 共時的な相互構成 | 同時に存在する二つの要素が、可能性と意味を与え合う |
| 抽象と具体 | 反復的な往復運動 | 具体から抽象が生まれ、抽象によって具体の見方が変わる |
したがって、これらを単純に「同じもの」として扱うのは正確ではありません。
ここで見ている共通点は、個々のメカニズムそのものではありません。共通しているのは、もともと一体の現象を人間が分節化した後に、「どちらが先か」という問いが事後的に発生する、という構造です。
分けることで、物事は見えやすくなります。しかし、分けた瞬間に、分けたもの同士の順序や主従関係を問うようになります。そして、その問い方自体が、分けた後の見方に依存しています。
抽象と具体は、時間の中で相互に修正される
具体がなければ、抽象は生まれません。
実際の機器、設定、ログ、障害、通信、性能、運用。そうした具体的な現象があるからこそ、「ネットワーク」「ルーティング」「可用性」「性能要件」「監視設計」といった抽象概念が生まれます。
一方で、具体だけをいくら並べても、それだけでは意味を持ちません。
BGP、OSPF、VRF、VLAN、ACL、NAT、CPU 使用率、メモリ使用量、セッション数、帯域、遅延。これらを単語として並べることはできます。
しかし、そこに抽象的な理解がなければ、何が本質なのかは見えてきません。どの要素が主で、どの要素が従なのか。どこが制約で、どこが可変なのか。どこが設計判断に関わり、どこが単なる実装詳細なのか。
それを見分けるためには、抽象化されたモデルが必要になります。
ただし、抽象は一度作れば完成するものではありません。具体を見て抽象を作る。その抽象を使って、もう一度具体を見る。すると、最初には見えていなかった制約や例外が見えてきます。その結果、抽象モデルそのものを修正する必要が出てきます。
ここに、抽象と具体の往復運動があります。具体が抽象を生み、抽象が具体の見方を変える。そして、変わった具体の見方が、さらに抽象を修正します。
HLD と LLD の関係
この関係は、インフラ設計における HLD と LLD を見ると分かりやすいです。
HLD では、システム全体の構造を定義します。拠点間接続、冗長化方針、セキュリティ境界、トラフィックの流れ、障害時の切り替わり方、運用上の責任分界などを整理します。
ここで扱っているのは、個別の設定値ではありません。システムをどのような構造として成立させるかという、抽象的な設計です。
一方で LLD では、それを具体に落とします。VLAN ID、IP アドレス、インターフェース、BGP の AS 番号、経路制御、ACL、NAT、監視項目、機器ごとの設定などを決めていきます。ここで初めて、抽象的な設計方針は実装可能な形になります。
しかし、HLD が先に完成し、LLD がそれを一方的に実装するわけではありません。
LLD に落とした段階で、機器仕様の制約、冗長構成の限界、経路制御の副作用、運用負荷、監視の粒度、障害時の切り戻し手順などが見えてきます。その結果、HLD 側の前提や設計方針を修正することもあります。
つまり、HLD は LLD を導き、LLD は HLD を修正します。抽象が具体を導き、具体が抽象を修正する。ここに、設計における往復運動があります。
分けた瞬間に、順序問題が生まれる
重要なのは、最初から抽象と具体が完全に別々のものとして存在しているわけではない、という点です。
現実には、構造、動作、制約、目的、意味が絡み合った一つの現象があります。それを人間が理解するために、「抽象」と「具体」に分けています。
分けることで、物事は見えやすくなります。しかし、分けた瞬間に別の問題も生まれます。それが、「どちらが先か」という問いです。
| 問い | 見落としやすいこと |
|---|---|
| 抽象が先か、具体が先か | 抽象と具体は相互に修正される |
| 設計が先か、実装が先か | 実装上の制約が設計を変えることがある |
| 要件が先か、構成が先か | 構成上の制約が要件の現実性を左右する |
| 監視が先か、運用が先か | 運用で必要な判断が監視項目を決める |
こうした問いは、もともと一体だったものを分けて考えることで生まれます。もちろん、分けること自体が悪いわけではありません。人間は物事を分けなければ理解できません。
問題は、分けた後に、その分け方を絶対視してしまうことです。
本来は相互に依存しているものを、片方だけが先にあるかのように扱う。あるいは、片方だけを見て全体を理解したつもりになる。そこから、設計の誤りや判断のズレが生まれます。
具体だけでは作業になる
技術の現場では、具体だけを追いかける人がいます。
製品名、設定項目、コマンド、画面操作、パラメータ、手順。もちろん、それらは必要です。
しかし、それだけでは設計にはなりません。具体だけを見ていると、なぜその設定が必要なのか、なぜその構成にするのか、どの制約を満たそうとしているのかが見えなくなります。
その結果、作業はできるが、判断ができない。手順はなぞれるが、未知の状況に対応できない。製品は操作できるが、構造を説明できない。
抽象なき具体は、作業になりやすいのです。
抽象だけでは空論になる
逆に、抽象だけを語る人もいます。
方針、構想、戦略、最適化、可視化、効率化、標準化。これらの言葉は一見すると立派に見えます。
しかし、具体に落ちない抽象は危ういです。どのデータを使うのか。どの機器で実現するのか。どの性能限界を前提にするのか。どの運用負荷を許容するのか。どの障害パターンを想定するのか。
こうした具体に接続できなければ、その抽象は現実を動かせません。
具体なき抽象は、空論になりやすいのです。
設計とは、分けたものを再び接続することである
設計とは、抽象だけを語ることではありません。具体だけを積み上げることでもありません。
現実の制約を見て、そこから抽象化されたモデルを作る。そのモデルをもとに、具体的な構成へ落とす。そして、検証や運用を通じて、再びモデルを修正する。設計とは、この往復運動です。
具体から抽象へ。抽象から具体へ。そして、また具体から抽象へ戻る。この往復ができるから、単なる作業ではなく設計になります。
分けることは理解のために必要です。しかし、分けただけでは設計にはなりません。分けたもの同士を、もう一度関係づける必要があります。
抽象と具体。設計と実装。要件と構成。監視と運用。それらを別々のものとして扱うだけではなく、どのように依存し合っているのかを見る。その依存関係を理解し、必要に応じて行き来する。そこに設計の本質があります。
設計で見るべきこと
「どちらが先か」と問う前に、分けたもの同士がどのように依存しているのかを確認した方がよいです。抽象は具体から生まれますが、具体は抽象によって意味を持ちます。そして、その抽象は具体によって再び修正されます。
「どちらが先か」ではなく「どう依存しているか」
ここまで見てきたように、「どちらが先か」という問いは、対象を分けた後に生まれることが多いです。
そのため、順序だけを決めようとすると、かえって本質を見失います。重要なのは、どちらが先かではありません。分けたもの同士が、どのように依存し合っているのかを見ることです。
抽象は具体から生まれます。しかし、具体は抽象によって意味を持ちます。そして、その抽象は、具体によって再び修正されます。
設計に必要なのは、この依存関係を見失わないことです。
この1冊ですべてわかる 新版 SE の基本
Amazon で見るまとめ
「卵が先か、鶏が先か」という問いは、単なる言葉遊びではありません。
そこには、人間が一体の現象を分けて理解しようとした後に、順序や主従の問いが事後的に生まれる、という構造があります。
もちろん、卵と鶏、ハードウェアとソフトウェア、抽象と具体は、同じ仕組みで成り立っているわけではありません。しかし、分けた後に「どちらが先か」と問うようになる点では共通しています。
だから重要なのは、順序を決めることではありません。分けたもの同士が、どのように依存し合っているのかを見ることです。
抽象なき具体は、ただの作業になります。具体なき抽象は、ただの空論になります。
設計とは、そのどちらにも落ちないために、分けたものを再び接続する行為です。


