オブジェクト指向はなぜ生まれたのか —— プログラマたちを救った「考え方」の物語
プログラミングを学んでいると、いつか必ず「オブジェクト指向」という大きな壁に出会います。
class を書いて、private をつけて、インスタンスを作って……。文法は教わったとおりに書けるのに、「で、結局これって何がうれしいの?」という気持ちがずっと残る。そういう人はとても多いです。
実はこれ、あなたのせいではありません。オブジェクト指向は「文法」から学ぶと、いちばん大事な部分が見えなくなるからです。
オブジェクト指向は、ある日天才が思いついた便利な書き方ではありません。何十年もかけて、世界中のプログラマが「もうこのままじゃ無理だ」と追い詰められた末に、たどり着いた苦肉の策です。
だから、本当の意味で腑に落ちるには、彼らが何に困っていたのかを知るのがいちばんの近道なんです。今日はその物語を、最初から順番にたどってみましょう。

第1章 昔、プログラムは「命令の長い行列」だった

コンピュータが生まれたばかりのころ、プログラムというのは、ただひたすら命令を上から順番に並べたものでした。
「この数を足せ」「ここに保存しろ」「もし0だったらここに飛べ」。そういう指示が一行ずつ並んでいる。プログラマの仕事は、コンピュータにやってほしいことを、正しい順番で書き並べることでした。
これは、プログラムが小さいうちは何の問題もありません。あなたが今書いている、数十行のコードを思い浮かべてください。上から下まで全部見渡せて、どこで何をやっているか頭に入っている。とても快適です。
世界も最初はそうでした。プログラムは数百行、せいぜい数千行。一人の頭の中に、全部が収まっていたのです。
第2章 プログラムが大きくなりすぎた日

ところが、コンピュータが世の中の役に立つとわかると、人々はもっと大きな仕事を任せたくなりました。
銀行のシステム、航空機の予約、企業の給与計算。プログラムは数万行、数十万行へと、あっという間に膨れ上がっていきます。
すると、奇妙なことが起こり始めました。
ハードウェアはどんどん速く、安くなっているのに、ソフトウェアだけが完成しない。 予定どおりに動かない。バグが取れない。直したはずの不具合が、別のところで再発する。納期は延び、予算は膨らみ、ついには「もう誰にも全体が把握できないプログラム」が生まれてしまいました。
1968年、世界中の専門家がこの問題を話し合うために集まり、こう名づけました ——「ソフトウェア危機(Software Crisis)」。
危機、です。それくらい深刻だったんです。
では、いったい何が彼らを追い詰めていたのでしょうか。犯人は、意外なところにいました。
第3章 真犯人は「データ」だった

プログラムが大きくなって何がいちばん困るのか。それは「処理(命令)が増えること」ではありませんでした。
本当の犯人は、データがどこからでも自由に書き換えられてしまうことだったのです。
たとえば、簡単なゲームを手続き型(昔ながらの命令を並べる書き方)で作ってみましょう。
// プレイヤーや敵の状態が、そこら中に剥き出しで置いてある
int playerHp = 100;
int playerMp = 50;
int enemyHp = 80;
void Attack()
{
enemyHp -= 10; // 誰でも、どこからでも、勝手に減らせる
}
void Heal()
{
playerHp += 20; // HPの上限チェックは……いったい誰がやるの?
}
最初はこれで動きます。ところがプログラムが大きくなり、何十人もの人が関わり、何万行にもなったとき、こんなバグが起きます。
「プレイヤーのHPが、いつのまにか 250 になっている。なんでだ?」
playerHp という変数は、プログラムのどこからでも触れます。だから、HPを書き換えているコードがプログラム中に何十か所もあるかもしれない。回復処理、罠のダメージ、デバッグ用のコード、誰かが昨日追加した謎の処理……。
このうちのどれか一つが「上限チェックを忘れていた」だけで、バグになる。そして、その「どれか」を探し出すのが地獄なのです。
これが、ソフトウェア危機の正体でした。規模が大きくなると、人間の頭は「どのデータを、どこで、誰がいじっているか」を追いきれなくなる。 命令の数ではなく、データの管理に人間の限界が来ていたのです。
第4章 発想の転換 —— 世界を「モノ」として見る

この行き詰まりを破ったのは、まったく違う角度からの発想でした。
時は1960年代、ノルウェー。オルヨハン・ダールとクリステン・ニガードという二人の研究者が、船の航行や交通の流れをシミュレーションするプログラムを作ろうとしていました。
シミュレーションというのは、現実の世界を計算機の中に再現することです。海には何隻もの船がいて、それぞれが自分の速度、自分の積荷、自分の目的地を持って動いている。
ここで彼らは気づきます。
「現実の船は、自分の情報を自分で持っていて、自分で動いているじゃないか。だったらプログラムの中でも、船という"モノ"を一つのまとまりとして表現すればいいのでは?」
つまり、こういうことです。
これまでは「データ(HPや速度)」と「処理(動く・攻撃する)」を、別々の場所にバラバラに置いていました。それを、現実の"モノ"の単位でひとまとめにする。
船には船のデータと船の動きを。プレイヤーにはプレイヤーのデータとプレイヤーの行動を。一つの箱に閉じ込めてしまう。
彼らが作った言語は Simula(シミュラ) と呼ばれ、ここで「クラス」と「オブジェクト」という言葉が初めて登場しました。これがオブジェクト指向の出発点です。
第5章 「モノ」に責任を持たせる

この発想を、もう一歩おしすすめた人がいます。アメリカ・ゼロックス社の研究所にいたアラン・ケイです。
彼は「オブジェクト指向(object-oriented)」という言葉を広めた人物で、こんなイメージを持っていました ——生き物の細胞です。
私たちの体は、何十兆もの細胞でできています。一つひとつの細胞は、自分の中身を膜で守っていて、外から勝手に内臓を引きずり出されたりはしません。やり取りするときは、決められた信号(メッセージ)だけを送り合う。
それでいて全体としては、ちゃんと一つの生き物として動いている。
「プログラムもこうあるべきだ」とアラン・ケイは考えました。
つまり、それぞれのオブジェクトが自分のデータを自分で守り、自分に関するルールに責任を持つ。 外からは、決められた窓口を通してしかお願いできない。
この「中身を守る」という考え方を、カプセル化(encapsulation) と呼びます。薬のカプセルのように、大事なものを包んで守るイメージです。
では、第3章のゲームのコードを、この考え方で書き直してみましょう。
public class Player
{
private int hp = 100; // 外からは直接さわれない(private)
private const int MaxHp = 100;
// HPを増やすときのルールは、Player自身が責任を持つ
public void Heal(int amount)
{
hp += amount;
if (hp > MaxHp) hp = MaxHp; // 上限チェックは、ここに一回書けばいい
}
public int Hp => hp; // 外からは「見る」だけ
}
何が変わったか、わかるでしょうか。
hp は private になり、Playerの外からは一切さわれなくなりました。 HPを変えたければ Heal() を呼ぶしかない。そして上限チェックは Heal() の中に一回だけ書いてあります。
つまり、「HPに関するルールは、Playerクラスの中にしか存在しない」 という状態を作れたのです。
ここでもう一度、第3章のあのバグを思い出してください。「HPが250になっている、原因不明」。
カプセル化された世界では、このバグは起きにくくなります。なぜなら、HPを書き換える方法がたった一つの窓口に限定されているから。探す場所が、プログラム全体から、たった一つのクラスの中に絞られるのです。
これこそが、ソフトウェア危機への答えでした。プログラムが何十万行になっても、「このデータの面倒を見ているのは誰か」がはっきりしていれば、人間はそれを追いかけられる。 オブジェクト指向は、コンピュータのためではなく、人間の頭の限界に合わせて生まれた考え方なんです。
第6章 だから、C#のクラスはこの形をしている

ここまで来ると、いつも丸暗記していた文法が、急に意味を持って見えてきませんか。
class——「データと処理を、一つのモノとしてまとめる箱」。ダールとニガードがシミュレーションのために考えた、あの発想そのものです。private——「中身を外から守る膜」。アラン・ケイの細胞のイメージ。勝手にさわらせない、という意思表示です。publicのメソッド ——「外から使える窓口」。細胞が信号をやり取りするための、決められた入口です。
class や private は、覚えるべき呪文ではありません。「データを守って、責任の置き場所をはっきりさせたい」という長年の願いが、言語の文法になったものなのです。
その後、ダールたちのSimulaに影響を受けて生まれた C++、その流れをくむ Java や C# へと、この考え方は受け継がれていきました。あなたが今書いているC#のコードは、ソフトウェア危機と戦った人々の知恵の、いちばん新しい姿なのです。
まとめ —— オブジェクト指向は「人間への思いやり」
最後に、いちばん大事なことをお伝えします。
オブジェクト指向は、コンピュータを速くするための技術ではありません。コンピュータは、データがバラバラに置いてあっても平気で動きます。困るのは、いつだってそれを読み書きする人間のほうです。
- プログラムが大きくなると、人間は全体を把握できなくなる(ソフトウェア危機)
- 原因は、データがどこからでも書き換えられること(第3章の地獄)
- だから、データと処理を「モノ」の単位でまとめ(クラス)
- 中身を守り、責任の在り処をはっきりさせた(カプセル化)
オブジェクト指向とは、つまるところ 「未来の自分や、一緒に働く仲間が、混乱しないように書く」 という、人間どうしの思いやりの技術なのです。
これから class を書くとき、ぜひ自分にこう問いかけてみてください。
「このデータの面倒を見る責任者は、誰だろう?」
その問いに答えられるようになったとき、あなたは文法を覚えただけのプログラマから、オブジェクト指向で"考えられる"プログラマへと変わっています。
その日を、楽しみにしていてください。






ディスカッション
コメント一覧
まだ、コメントがありません