場面
1930年代のケンブリッジ。ルートヴィヒ・ウィトゲンシュタインは、自分が書いた本と格闘していた。
彼の最初の著作、1921年の『論理哲学論考(Tractatus Logico-Philosophicus)』は、哲学の世界で彗星のように現れた。その主張は過激なまでに整然としていた——言語は世界の構造を映し出す鏡だ。すべての命題は事実の絵画であり、すべての言葉は世界の中の何かを指示する。言葉の意味は、それが指し示すものによって固定される。
その本を書き上げたウィトゲンシュタインは「哲学の問題はすべて解決した」と言い放ち、一時は哲学を捨てた。オーストリアの田舎で小学校教師をした。修道院の庭師になろうとした。だが哲学は彼を手放さなかった。
ケンブリッジに戻った彼は、後の『哲学探究』§2 で読者にこんな光景を想像させることになる。建設現場で、職人が助手に向かって叫ぶ。「レンガ!(Ziegel!)」。助手はレンガを持ってくる。また叫ぶ。「板!(Platte!)」。板が来る。「梁!(Balken!)」「角石!(Würfel!)」——四つの単語だけで、建物が立ち上がっていく。
「レンガ!」は文ではない。主語もなく、述語もなく、論理的な命題構造もない。しかし、それは完全にコミュニケーションとして機能している。意味は、言葉の論理的形式の中にあるのではない。意味は、この建設現場という文脈の中で、職人と助手が共有する実践の中に宿っている。
ウィトゲンシュタインは自分の最初の著作が根本的に間違っていたことに気づいた。彼は今度は反論本を書き始めた。死後の1953年に出版されることになる『哲学探究(Philosophische Untersuchungen)』。そこで彼は言った——意味を問うな、使用を問え(Don’t ask for the meaning, ask for the use)。
答え
言語の意味は、その言語が使われる実践の共同体に属する。ウィトゲンシュタインはそれを「言語ゲーム(Sprachspiel)」と呼んだ。
チェスの「ビショップ(Bishop)」は、斜めに動く駒のことだ。カトリック教会の「ビショップ」は、司教職の位階のことだ。どちらが「本当の意味」なのか——この問いは無意味だ。二つの言語ゲームが存在するのだから。チェス盤の上という言語ゲームと、教会組織という言語ゲームと。
言語ゲームの境界は、意味の境界だ。
ある言語ゲームの中で完全に正確な発話が、別の言語ゲームに持ち込まれると突然意味を失う、あるいは危険な誤解を生む。翻訳が必要なのは、言語が違うからではない——言語ゲームが違うからだ。
そして重要なことがある。二つの言語ゲームが同じ言葉を違う意味で使っているとき、その不一致を「どちらかが間違っている」と解決しようとするのは誤りだ。それぞれの言語ゲームの中で、それぞれの使用は正しい。解決すべきは、意味の統一ではなく、境界の明確化だ。
CS への翻訳
エリック・エヴァンスが2003年に『ドメイン駆動設計』を書いたとき、彼はウィトゲンシュタインの名前を挙げなかった。しかし二つの中心概念は、言語ゲーム論の直接の翻訳として読むことができる。
ユビキタス言語(Ubiquitous Language)——開発者とドメイン専門家が共有する、そのコンテキストの中だけで使われる言語。「受注」「顧客」「在庫」といった言葉は、その業務コンテキストで実際に使われている言語ゲームから直接引き取る。「汎用的な意味」を探して定義するのではなく、この実践の共同体の中での使用を問う。
境界づけられたコンテキスト(Bounded Context)——言語ゲームが有効な境界の明示化だ。「注文(Order)」という言葉を考えてみよう。
営業チームにとって「注文」とは、顧客が何を・いくらで・どんな割引で購入するかという意図の記録だ。顧客IDが紐づき、価格交渉の経緯が残り、失注した場合の理由も管理される。
配送チームにとって「注文」とは、何を・どこに・いつ届けるかという物理的な指示だ。倉庫のどの棚から何個ピッキングするか、どの配送業者に委託するか。顧客の名前が「山田太郎」でも「Y. Yamada」でも、それは梱包作業には関係ない。
どちらが「本当の注文の意味」なのか——ウィトゲンシュタインはこの問いを間違いと呼ぶだろう。二つの言語ゲームが存在するのだ。
graph LR
subgraph 営業コンテキスト
O1["注文(Order)\n- 顧客の意図\n- 価格・割引\n- 商談経緯\n- 顧客ライフタイム"]
end
subgraph 配送コンテキスト
O2["注文(Order)\n- 配送先住所\n- ピッキングリスト\n- 配送業者\n- 梱包仕様"]
end
subgraph 翻訳層 / 腐敗防止層
T["Anti-Corruption Layer\nOrderToShipmentTranslator\n\n意味の変換・検証"]
end
O1 -->|"OrderPlaced イベント"| T
T -->|"ShipmentRequest"| O2
style T fill:#fff3cd,stroke:#ffc107
style O1 fill:#d4edda,stroke:#28a745
style O2 fill:#d4edda,stroke:#28a745
エヴァンスが導入した「腐敗防止層(Anti-Corruption Layer)」は、言語ゲームの境界で翻訳を担う仕組みだ。異なるコンテキストが直接会話しようとすると、意味が腐敗する——一方の言語ゲームの意味が、もう一方に侵食してくる。翻訳層がその境界を守る。
設計への示唆
チームが「『注文』の定義をシステム全体で統一しよう」という議論を始めたとき、それは往々にして解くべき問題を間違えている。
❌ 間違ったアプローチ:単一の正規定義を探す
// 全コンテキストで共有される "Order" クラスを作ろうとした結果
class Order {
String orderId;
Customer customer; // 営業が必要
List<OrderItem> items; // 両方が必要(でも意味が違う)
DiscountPolicy discount; // 営業だけが必要
ShippingAddress address; // 配送だけが必要
Carrier carrier; // 配送だけが必要
SalesHistory history; // 営業だけが必要
// ...
// 気づけば誰の言語ゲームにも属さない「万能クラス」のできあがり
}
このクラスは、二つの言語ゲームを無理やり一つの言葉に押し込んだ結果だ。誰のために書かれたのかわからない。どちらのチームにとっても「余計なものが入っている」という感覚が残る。変更のたびに、もう一方への影響を心配しなければならない。
✅ 正しいアプローチ:境界を引き、境界で翻訳する
// 営業コンテキストの言語ゲーム
class SalesOrder {
OrderId id;
CustomerId customerId;
List<LineItem> lineItems;
DiscountPolicy appliedDiscount;
SalesRepId ownedBy;
// 「注文」が何を意味するかは、営業の言語ゲームが決める
}
// 配送コンテキストの言語ゲーム
class ShipmentOrder {
ShipmentId id;
DeliveryAddress destination;
List<PackageItem> packages;
CarrierId assignedCarrier;
// 「注文」が何を意味するかは、配送の言語ゲームが決める
}
// 腐敗防止層:言語ゲームの境界での翻訳
class OrderToShipmentTranslator {
ShipmentOrder translate(SalesOrder salesOrder) {
// 意味の変換。営業コンテキストの言語を配送コンテキストに翻訳する
return new ShipmentOrder(
new ShipmentId(salesOrder.getId()),
extractDeliveryAddress(salesOrder),
convertToPackages(salesOrder.getLineItems()),
selectCarrier(salesOrder)
);
}
}
二チームが「同じ言葉」で争っているとき、その争いはたいてい解決するものではなく、分離するものだ。
ウィトゲンシュタインが建設現場で気づいたように——「レンガ!」の意味は、この建設現場という実践の中にある。その意味を辞書に書いて固定しようとしたとき、それはもう言語ゲームではなくなる。
コードの設計においても同じだ。あなたのシステムが何を「注文」と呼ぶかは、あなたの業務という言語ゲームが決める。そして業務が複数の文脈を持つなら、「注文」も複数の意味を持ってよい。矛盾ではない——それが自然な言語の姿だ。
問い:チームが同じ言葉で話しているのに、なぜかすれ違う。そのとき最初に疑うべきは「定義の曖昧さ」か、それとも「言語ゲームの違い」か?