「三大」

例の OOP の三大要素「カプセル化(≒情報隠蔽)」「継承」「ポリモーフィズムは、有名なわりには「詠み人知らず」で、しかもあまり良いモノではありません。

sumim さんによれば、もともとはC++でのOOPを説明する要素から「抽象データ型」「継承」「動的結合」の三つが抜き出され、その後変化した物だと思われるそうです。(オブジェクト指向の概念の発明者は誰ですか?(改訂版) - Smalltalkのtは小文字です)。

そのようは背景から、「三大」は 静的OOPLに偏っており、しかも C++ 界隈ですら、C++ プログラミングスタイルの進化から取り残され、古びて現状に一致しなくなっており、21世紀に入ってからのまともな C++ 本で そのままを使っているのをわたしはみたことがありません。

この「三大」を 「OOPとは何か」の文脈で 取り上げるメリットはもうないのです。(デメリットならたくさんありますが...)


さて、そのような状況ですので、ここは素直に「三大?なにそれ?」と黒歴史化するのが正しい大人の有り様ではあるのですが、そこをあえて、もしこの「三大」の現代版をあなたがでっち上げるとするならば?・・・、というお題に取り組んでみました。

なかなかパズルとして歯ごたえがありますし、自分のOOP の理解度をセキララnしてしまうという意味でも面白いのでないかな?・・と思います。

え、わたし?うーん、そうですね。わたしなら、「(オブジェクトによる)抽象化(≒構造化)」「差分プログラミング」「ポリモーフィズムになるんじゃないかな、と考えます。


* * *


OOPにおいて抽象化は、オブジェクトというカプセルの中に詳細たるコードを詰め込み、カプセル自身にそれを意味する名前を与えることにより行います。これは構造化プログラミングにおいてプロシージャ(サブルーチン)というカプセルを用いて抽象化するのと全く同じ構図です。

OOPL は ポリモーフィズムを、型継承やダックタイピング(duck typing)、 総称(genericity) で実現し、差分プログラミングを、実装継承や集約(委譲)で実現します。

抽象化は、先の構造化プログラミングの例のように、必ずしもオブジェクトで行う必要はありません。それをオブジェクトで行うモノを OOP と呼ぶだけです。ただし、オブジェクトがクラスのインスタンスである必要はありません。

ポリモーフィズムと差分プログラミングは、それが出来る必要がりますが、どのような方法で実現するかは問いません。 OOP の進化の歴史はこれらに対するアプローチの仕方の試行錯誤でもあるといって良いでしょう。言語とその文化、状況によりどれが可能か/どれが好ましいかは変わるでしょう。

OOP/OOPLとは何か?の文脈で肝心なのは、「何を実現できるか」であり、「どの仕組みでやっているか」とは切り離すことだと思います。


* * *


以下蛇足。

このお題を考えるに当たり、まずは三大から「カプセル化」と「継承」は外すべきだなぁ・・から始めました。というのも「カプセル化」は buzzword 化が著しく(参考:カプセル化、情報隠蔽、データ隠蔽 - ぐるぐる~)、「継承」は 一つの機能で複数の重大な副作用を持つため混乱を招く(加えて、実はOOPL に必須ではない)からです。

カプセル化は「何かを隠蔽すること」と「隠蔽することによりもたらされるもの」のなんでもを指します。たとえば「データ隠蔽」をカプセル化と呼んだり、「実装が隠蔽されることによりポリモーフィズムが導かれる」をカプセル化と呼んだりします。

あまりにいろいろ過ぎて、かえって意味不明になっているのでここは一つに絞りたいところ。問題はなにをチョイスするかです。――うーん、難しい。

けれどもOOPの文脈では「カプセル」はオブジェクトであることは不変ですし、ならばここはシンプルに「オブジェクトによる抽象化」をチョイスするのが「わかりやすい」かな?と思いました。

次に継承。継承を「三大」の中で掲げてしまうことは、

  • 「型継承」と「実装継承」という全く性質が異なるものを一即多に扱わせてしまうことが有害(混乱を生む)
  • (強いて加えるなら)「継承がOOPに必須」とすることでポリモーフィズムを継承の興味深い副作用のように感じさせてしまう危険性がある

と言った点が心配です。とはいえ、典型的な静的OOPL では継承を抜きにOOPL を語るのは骨抜きすぎます。そこで 「継承」そのものではなく「継承が(典型的な静的型付け言語に)もたらすもの」 にシフトさせることにしました。

OOPL界では「手段は異なるが同じようなことが実現出来る。だから俺もOOPLだ!」みたいな名乗り上げるのが伝統ですし、このシフトにより難関であった動的OOPL やプロトタイプベースOOPL にも対応できるものになります。具合がいいかな、と思いました。


さてさて、この「あなたなら『三大』をどう作る?」というお題ですが、きっかけは オブなぜ本2のレビューネタです。

オブなぜ本は OOP を 三大要素――を平澤さんがアレンジしたもの(「カプセル化」を「クラス」に置き換え*1)を軸に説明していて、うーん、なんか微妙に歪な気がするから突っ込もうか・・・でも間違いだとバッサリするのはそれはそれで問題だなぁ、と、あーでもない、こーでもないしてたのですが、じゃあ「まず、わたしならどう書くのだろう、を考えてみよう」をしてみたら、お題として面白かったという次第。

気がつけば、なんだか大喜利のようになってしまいましたが、みなさま如何でしたでしょうか。もし他の方がのっかてきてくれるのなら、なんだか人により答えが様々になりそうで、面白そうであり、恐ろしくもあります。sumim さんのような含蓄の深い人が選ぶ3つは凄そうです。

そしてわたしの座布団は、はたして無事だったのでしょうか、はてさて。

*1:2版で追加された注釈ではさらに「『継承』を『実装の継承』、『ポリモーフィズム』を『インターフェイスの継承』と呼ぶこともある・・みたいな事もちょこっとだけ追加されています。確かに、動的OOPL(「ポリモーフィズム」が「型継承」に依存しない流儀の言語)をハブれば、「抽象データ型」「型継承(含むポリモーフィズム)」「実装継承」で三大を構成するのは良さげです。でもオブなぜ本の本文と合わせるとなぜだか「コレジャナイ感」が漂ってる気がするのですよね