場面
紀元前5世紀のアテネ。港の一角に、一隻の船が永遠に繋がれていた。
テセウスがクレタ島のミノタウロスを倒して帰還したとき、アテネの市民はその船を聖遺物として保存することにした。英雄の偉業を刻んだ木造船。しかし、木は腐る。毎年、腐った板が新しいものに交換された。二十年が経ち、五十年が経ち、百年が経った。
プルタルコスが紀元後100年ごろに記録したとき、船のどこにも元の木材は残っていなかった。すべての板が、すべての梁が、すべての帆柱が、一枚一枚、一本一本、新しいものに置き換えられていた。それでもアテネ市民は変わらず「テセウスの船」と呼んでいた。
ここで哲学者たちは立ち止まった。——本当に、これはテセウスの船なのか?
十七世紀になって、トマス・ホッブズがこの問いに更なる刃を突き刺した。もし誰かが取り替えられた古い板を一枚ずつ丁寧に保管し、最後にそれをすべて使って船を組み直したとしたら——今、港には二隻の船がある。どちらが「本物の」テセウスの船なのか。
一方は切れ目のない連続性を持っている。板が一枚ずつ交換されながらも、アテネの港でずっと揺れ続けていた。もう一方は完全な物質的同一性を持っている。テセウスが実際に乗り込んだ一枚一枚の板でできている。同一性とは、いったい何なのか。
答え
ホッブズとその後の哲学者たちが辿り着いた洞察は、単純だが深い。
同一性は物質的構成から切り離される。
「同じもの」であるためには、すべての属性が一致している必要はない。むしろ、物質が完全に入れ替わっても「同じ」と言えるケースがある。それは、変化を貫いて続く何らかの連続性のスレッド——歴史、追跡可能性、文脈——が存在するからだ。
逆もまた真である。二つのものが全属性で完全に一致していても、異なる存在でありうる。ホッブズの二隻の船は、いかなる属性を見ても区別がつかないかもしれない。しかし、それらは異なる歴史を持つ。
哲学の言葉を借りれば: identity(同一性)は qualitative identity(属性の一致)とは別物である 。「同じに見える」ことと「同じものである」ことは、根本的に異なる問いだ。
CS への翻訳
この問いがコンピュータサイエンスに持ち込まれたのは、2003年のことだ。
エリック・エヴァンスは『ドメイン駆動設計』(Domain-Driven Design)の中で、ドメインモデルを構成するオブジェクトを二つの種類に分けた。Entity と Value Object である。
エヴァンスの定義は、テセウスの問いへの直接の答えとして読むことができる。
Entity(エンティティ) とは、属性が変化しても追跡される同一性を持つオブジェクトだ。顧客は Entity だ。名前が変わっても、メールアドレスが変わっても、住所が変わっても、それは「同じ顧客」である。その顧客を識別するのは、属性の集合ではなく、ID という連続性のスレッドだ。テセウスの船が、板が全部変わっても「テセウスの船」であり続けるように。
Value Object(値オブジェクト) とは、属性の組み合わせ自体がその同一性であるオブジェクトだ。「1,000円」という金額は、どの千円札であれ、どの銀行口座の残高であれ、1,000円は1,000円だ。一円でも変わったら、それはもう別の金額だ。属性が変われば同一性が変わる——これがホッブズの「古い板を集めた船」の論理だ。
flowchart TD
A["このオブジェクトをモデリングするとき"] --> B{"時間とともに属性が\n変化するか?"}
B -->|Yes| C{"変化後も「同じもの」\nとして追跡する必要があるか?"}
B -->|No| D["Value Object として設計する\n(構造的等値性・イミュータブル)"]
C -->|Yes| E["Entity として設計する\n(ID で同一性を追跡)"]
C -->|No| D
E --> F["例:顧客・注文・ユーザー\nIDを持ち、属性変化を記録する"]
D --> G["例:金額・日付・住所(コピー)\n同じ値なら交換可能"]
style E fill:#d4edda,stroke:#28a745
style D fill:#d4edda,stroke:#28a745
style F fill:#f8f9fa,stroke:#6c757d
style G fill:#f8f9fa,stroke:#6c757d
エヴァンスが明示的にホッブズやプルタルコスを引用したわけではない。しかし構造的な並行性は偶然ではないだろう。同一性とは何か——この問いは哲学が二千年かけて彫刻し、ソフトウェア設計者が2003年に再発見した。
設計への示唆
この区別を知らずにモデリングしていると、どんな問題が起きるか。
❌ よくある誤り:すべてを Entity にする
「安全のために」と言って、すべてのオブジェクトに ID を振る。金額にも、座標にも、色にも。するとコードベースが ID だらけになる。等値比較のたびに ID を引き出す必要が生じ、意図しないIDの共有バグが生まれ、「同じ」という概念がコード上で曖昧になる。
// ❌ 金額を Entity として扱ってしまった場合
class Money {
constructor(
public readonly id: string, // なぜ金額に ID が?
public readonly amount: number,
public readonly currency: string
) {}
}
const a = new Money("id-001", 1000, "JPY");
const b = new Money("id-002", 1000, "JPY");
a === b // false... でも意味的には「同じ金額」では?
✅ 正しい設計:Value Object として金額を扱う
// ✅ 金額を Value Object として設計する
class Money {
constructor(
public readonly amount: number,
public readonly currency: string
) {}
equals(other: Money): boolean {
return this.amount === other.amount && this.currency === other.currency;
}
add(other: Money): Money {
if (this.currency !== other.currency) throw new Error("通貨が異なります");
return new Money(this.amount + other.amount, this.currency);
}
}
const a = new Money(1000, "JPY");
const b = new Money(1000, "JPY");
a.equals(b) // true — これが意味的に正しい
Value Object をイミュータブルにすることには、哲学的な必然性がある。「1,000円を変化させて500円にする」のは、テセウスの船の板を取り換えるのとは違う。それは単に「別の金額を作る」ことだ。したがって、add() は既存のオブジェクトを変化させるのではなく、新しい Money を返す。
ホッブズの捻りを分散システムに当てはめると
ホッブズの「二隻の船」問題は、今日の分散システム設計に直結する。同じデータが二つのデータベースに存在し、ネットワーク障害の間に別々に更新されたとする。どちらが「本物の」注文なのか。
この問いへの答えは、Entity の設計時に「同一性のスレッド」として何を選んだかによって決まる。IDだけではなく、どのバージョンを真実とみなすか——この競合解決の戦略こそが、同一性の定義そのものだ。これは第5話(CAP定理)が突きつける選択にも直接つながる:分断の両側で「同じ Entity」が別々に変化したとき、何をもって「同じ」とするのか。
「同一性のスレッド」は、何でできているか
Entity の同一性が「変化を貫いて続く何か」だとして——その「何か」をどこに記録するか。ID 列だけでは、属性の変遷の理由は何も残らない。テセウスの船が「板を取り換えた」という事実だけは記録できても、「なぜ取り換えたか」「いつ・誰が判断したか」は失われる。
第3話で扱う イベントソーシング は、この「同一性のスレッド」を文字通り編んでいく仕組みだ。Entity の同一性 ID を主キーに、その Entity に起きたすべての出来事を時系列で積み上げる。テセウスの船で言えば、「2026-04-01:船首の第3板を交換、理由:腐食」というイベントの列がそのまま船の歴史になる。Entity の本体が「現在の属性のスナップショット」ではなく「出来事の累積」になる——この設計判断ができるのは、同一性が物質的構成と切り離せるという、テセウスから続く哲学的洞察の上に立っている。
設計上の根本的な問い:このオブジェクトは、その属性が変わっても「同じもの」として追跡される必要があるか?
答えが「Yes」ならば Entity を選べ。答えが「No」ならば Value Object を選べ。そしてその判断は、属性の便宜ではなく、ドメインの意味論から導け。テセウスの船が何であるかを決めるのは、船大工ではなくアテネ市民——すなわち、ドメインの言語共同体だ。
「ドメインの言語共同体が決める」——この一言には、もう一段深い問題がある。何をもって「同じ」と呼ぶかは、コミュニティの言語実践そのものに埋め込まれている。「Order」を「同じ注文」と呼ぶ条件は、営業チームと配送チームで違うかもしれない。同一性の問いはやがて、意味そのものがどこに宿るのかという問いに溶け出す。第2話、ウィトゲンシュタインの言語ゲームへ。
問い:あなたが今モデリングしているオブジェクトの「同一性のスレッド」は、ID列の中にあるか、属性の中にあるか、それとも歴史の中にあるか。三つは違う設計を要求する。