OOPの本質はメッセージング――アラン・ケイが語った本当のOOP
OOPを学ぶと、まず継承・カプセル化・ポリモーフィズムの3語を暗記しがちです。
しかし「オブジェクト指向プログラミング」という言葉を作ったアラン・ケイは、その3つを核心とは考えていませんでした。
先に結論を言うと、アラン・ケイが語った本当のOOPの本質は、オブジェクトそのものではなく、オブジェクト間で交わされるメッセージです。クラスをどう分けるかより、オブジェクト同士が何をやり取りするかが先なのです。
最後まで読めば、なぜ彼が「オブジェクト指向という名前を後悔している」とまで言ったのか、そしてその視点がコードをどう変えるのかが見えてきます。
アラン・ケイはなぜ「OOP」という名前を後悔したのか?
アラン・ケイは1970年代、Xerox PARCでSmalltalkを作った人物です。「オブジェクト指向プログラミング」という用語も彼が生み出しました。
2003年、ある開発者からメールで「OOPとは何か」と尋ねられた彼は、こう答えました。
「私は『オブジェクト』という言葉を使ったことを後悔している。
人々の関心を、それほど重要でない概念に向けてしまったからだ。本当に大きなアイデアは『メッセージング』だ。」
初めて読むと少し戸惑いますよね。私たちが学んだOOPは、いつも「オブジェクトをうまく設計する方法」だったからです。
ケイにとって本当に重要なのは、オブジェクトの内部ではありません。オブジェクトがメッセージを交わして生み出す関係と相互作用こそが、システムの本質なのです。
彼はプログラムを生物の細胞にたとえました。細胞はそれぞれ内部を隠し、化学信号、つまりメッセージだけで通信します。インターネットも同じです。無数のコンピューターが独立して動きながら、メッセージだけをやり取りします。
メッセージ中心の考え方は何が違うのか?
「メソッドを呼び出す」と「メッセージを送る」は似ていますが、視点が異なります。
メソッド呼び出しは「このオブジェクトのこの関数を実行して」に近いものです。送信側は受信側の内部をある程度知る必要があります。
一方、メッセージは「これを処理して。方法は任せる」に近いものです。送信側が欲しいのは結果だけで、相手がどう処理するかを知る必要はありません。
例を見てみましょう。会員ランクごとのオブジェクトに、割引計算を「メッセージ」として委譲するコードです。
protocol Member {
func discountedPrice(for price: Int) -> Int
}
struct Gold: Member {
func discountedPrice(for price: Int) -> Int { price * 80 / 100 }
}
struct Silver: Member {
func discountedPrice(for price: Int) -> Int { price * 90 / 100 }
}
// 送信側はランクごとの計算方法をまったく知りません.
let members: [Member] = [Gold(), Silver()]
for m in members {
print(m.discountedPrice(for: 10000))
}
// 出力: 8000
// 出力: 9000
呼び出し側のコードにはif文もランク名もありません。
「割引価格を計算して」というメッセージを送るだけで、実際の計算は各オブジェクトが担当します。新しいランクが増えても、呼び出し側を変更する必要はありません。
これがケイの語ったメッセージングの力です。目的はオブジェクトを細かく分割することではなく、結合を弱めるコミュニケーション方法が核心なのです。
では、カプセル化とポリモーフィズムは不要なのか?
いいえ。むしろ逆です。
メッセージングを真剣に捉えると、カプセル化とポリモーフィズムは自然についてきます。
オブジェクトがメッセージだけで通信するには、内部状態を隠す必要があります。それがカプセル化です。同じメッセージにオブジェクトごとに異なる反応をすることがポリモーフィズムです。
これらは暗記すべき規則ではなく、メッセージ中心に設計すれば自然に導かれる結果です。
問題は順番です。多くの人は「まずクラスをうまく分けよう」と始めます。するとオブジェクトは増えますが、互いの内部を丸見えにする、名前だけオブジェクト指向のコードになりがちです。
ケイの視点は順番を逆にします。「このオブジェクトはどんなメッセージに応答すべきか?」を先に問うのです。
この視点はいつ使い、いつ力を抜くべきか?
メッセージ中心設計が常に正解とは限りません。状況に応じて使うことが大切です。
| 状況 | 判断 |
|---|---|
| 要件が頻繁に変わるドメインロジック | メッセージ中心の委譲構造が有利 |
| 協調するオブジェクトが多い複雑なフロー | 結合度の低減に大きな効果 |
| 単純なデータ変換・計算スクリプト | 無理にオブジェクトで包まず、関数にする |
| 性能が極めて重要な部分 | 過度な抽象化はかえって負担になる |
まとめると、こうです。
- 協調と変更が多い場所ほど、メッセージという視点が生きます。
- 単純で固定されたロジックは、力を抜くほうがよいでしょう。
- 目的は「オブジェクトを分けること」ではなく、「コミュニケーションを設計すること」だと覚えておいてください。
面接ではこう聞かれます
Q. アラン・ケイが語ったOOPの本質は何ですか?
オブジェクトそのものではなく、オブジェクト間で交わされるメッセージです。ケイはオブジェクトを独立して通信する細胞にたとえ、継承やカプセル化よりメッセージングを大きなアイデアと考えました。
Q. メッセージ中心設計には、実務上どんな利点がありますか?
呼び出し側が相手の内部実装を知らなくてもよいため、結合度が下がります。その結果、新しい型を追加しても呼び出し側を直さずに済み、変更に強い構造になります。
OOPを難しく感じたら、クラス図を描く前に「このオブジェクトたちは互いに何を話しているのだろう?」と考えてみてください。
視点を一つ変えるだけで、コードがずっと堅牢になるのを感じられるはずです。今日もよい設計を!

