2016年06月23日

できるだけわかりやすく説明してみるという実験:オブジェクト指向という発明(その1)

この世のプログラマーは二種類に分けられる。
「オブジェクト指向」が分かっているプログラマーと、分かっていないプログラマーだ。
この壁は大きい。

そいういう僕も、中学生のころからプログラミングをやっていて、やがてプロとしてそれを生業にするようになったのだが、プロになった後でこの「オブジェクト指向」を理解しようとしてかなり苦しんだ。

僕にオブジェクト指向を叩き込んでくれた師匠が常に言っていたことであるが、一度、オブジェクト指向ではないプログラミング言語を学んだ後にオブジェクト指向を理解することは、それまで全くプログラミングをしたことのない人が学ぶよりも時間がかかる、とのこと。
確かにそうかもしれない。

オブジェクト指向が生まれる前のプログラミング言語は、「構造化言語」と呼ばれていたが、これはわかりやすく言うと、「全知全能の神」を作るプログラミング言語だ。

たとえば、商品を販売するシミュレーションをプログラムする際に、その商品を客が買うことができるかできないかを判断する方法を考えてみよう。
構造化言語で書くとするとそのアルゴリズムはだいたいこうだ。 

客が買おうとしている商品の値段と、客の財布の中身の総額を比較して、財布の中身の方が大きければ買うことができる。商品の値段の方が大きければ買えない。
さて、上記の文にはおかしな点がないだろうか?
なぜ売る側が客の財布の中身の総額を知っているのか?
これがさっき僕が「全知全能のプログラム」と言ったものである。

これをオブジェクト指向で書くと以下のようなアルゴリズムになる。
客が買おうとしている商品の値段を見て、客がいくら持っているかを聞く。もし客が答えた額が商品よりも大きければ買うことができる。商品の値段の方が大きければ買えない。  
正直言って、さっきのものよりもちょっと面倒くさくなったけど、これでちょっと現実っぽくなった。
だけど、客にいちいち「いくら持ってるねん?」って聞くか?
もうちょっと現実的にするために、さらに以下のように書き換えられる。
客が商品を買おうと思った時に、その商品の値段が自分の財布の中身の総額よりも小さいか大きいかを比べて、商品の額のほうが小さかったら買うことができる。大きければ買えない。シミュレーションプログラムは、客に「買うことができるかどうか?」を聞く。
うん、これでかなり現実に近づいたぞ。
ここでのポイントは「客だけが、その商品を買うことができるかどうかを知っている」ということ。シミュレーションプログラム(店側)は客に「買うことができるかどうか」を尋ねる、ということ。

二番目と三番目のものがオブジェクト指向のアルゴリズムで、ここでの「商品」、「客」、「シミュレーションプログラム(=店)」がそれぞれ「オブジェクト」というものである。

以上を見ていると、オブジェクト指向アルゴリズムは、1つ目の「全知全能プログラム」と比べてかなり面倒くさいことになっている。こんな面倒くさいことをするメリットはどこにあるのか?

上記の例はとても単純なものだったので正直なところ、全知全能型の方が短期間で間違いなくプログラミングできるものである。
が、実際のプログラムというものはこんな単純なものではなく、色々な登場人物が存在し、色々とややこしい条件が出てくる。ある期間だけ同じ商品を3個買ったら20円引き、この商品は18歳未満には売ってはならない、レジ袋がいらない客は1円引き、など。

全知全能型の場合、このようなややこしい条件をすべて知っている必要がある。全知全能なんだから。
「買うことができるかどうか?」という判断の際に、客の年齢を知っていなければならないし、今がキャンペーン期間か?→キャンペーン対象商品か?→3つ買うか?→20円引いた値段と客の財布の中身を比べて、、、
ということをすべてする必要がある。
これはプログラムがどんどん複雑化し、爆発して破綻する。

オブジェクト指向の場合は、それぞれのオブジェクトの内側で完結することになる。
それぞれの商品だけが、自分がキャンペーン対象かどうかを知っている。買う時に店に聞かれたら自分がキャンペーン対象かどうかを答える。それまで店側は知らない。
客の年齢は客だけが知っている。買う時に(以下同文)。

それぞれのオブジェクトがそれぞれの内側で完結していることで、そのルールに変更があった場合でも、そのオブジェクトだけを書き換えるだけで済む。
あるキャンペーン商品のキャンペーン期間が延長になった場合は、商品オブジェクトが「自分がキャンペーン対象か否か」を判断する際のロジックのキャンペーン期間を書き換えるだけ。店側は何もしない。ただ「おまえはキャンペーン対象商品か?」と尋ねるだけ。

以上はオブジェクト指向のある側面だけを説明したものである。かなり実世界に近いものかと思う。
プログラムを設計する際には「モデル化」という言葉がよく使われるが、この「モデル化」という言葉も、オブジェクト指向が発明された以降に出てきた言葉で、それまでは「オブジェクトをモデル化する」という発想はなく、全知全能の巨大なプログラムが爆発して破綻する、を繰り返していたのである。

オブジェクト指向が発明された以降は、そういうことはもうないのか?といえば、まだまだある。
なぜなら、、、 

この世のプログラマーは、

「オブジェクト指向」が分かっているプログラマーと、分かっていないプログラマー

の二種類に分けられるから、だ。


【今回のまとめ】
  • 世のプログラマーは二種類に分けられる:「オブジェクト指向」が分かっているプログラマーと、分かっていないプログラマーだ。
  • オブジェクト指向が生まれる前のプログラミング言語は「構造化言語」と言われていた。
  • 構造化言語は、プログラム自らが「全知全能」となって、全体を把握しているように設計される。
  • オブジェクト指向は、オブジェクトごとにその内部で完結しているように設計する。
  • 構造化言語で設計されたプログラムは、規模が大きくなるにつれてどんどん複雑化し、プログラマの手に負えないものになって破綻することが多い。
  • オブジェクト指向で設計することで、プログラムの規模が大きくなっても、プログラムが爆発して破綻することなく、すっきりとしたものにできる。


OLランキングで1位になりたい!賛同していただける方は下記をクリック!