オブジェクト指向
プログラミング教育

オブジェクト指向に生命を持ち込むな!


この記事の内容

オブジェクト指向ってわかるようでわかんない!それはもしかしたらオブジェクト指向の世界に生命を持ち込んでいるからなのかもしれない...:scream: ウギャー

この記事は「オブジェクト指向と10年戦ってわかったこと」を書いた筆者が、オブジェクト指向の世界を正しくイメージするための思考法を提案したものです。


オブジェクト指向はSFの世界

長い間、僕はオブジェクト指向に疑問を抱いていました。「オブジェクト指向は現実世界をそのままソフトウェアに表現する」とよく言われるけれど、継承による機能受継ぎって現実世界ではどういう現象なんだろう?

コンピュータは現実より高速だし、気軽にコピーしたり削除したりできる。現実でオブジェクトを作るには生産に時間がかかるのにコンピュータは一瞬だ。遅刻しそうな時、カバンの中に荷物を詰め込んで駅までダッシュしたりするけれど、プログラムの世界でこれと似たようなことってあるだろうか?

いったいこんなに現実と差があるのに、何が「オブジェクト指向は現実世界をそのままソフトウェアに表現する」なんだろう。

僕がオブジェクト指向を学んで3年目に気がついたことは、オブジェクト指向の世界は四次元ポケットが存在するSFの世界だということです。

現実世界で何か作ろうとした時、途中で釘が足りないことに気がついて制作を断念させられることがあります。これは、現実世界は何が何処にどれだけあるのかの影響度が高いということです。

しかし、プログラムの世界は好きなものを好きな時に好きなだけ取り出せるので、このようなことは起こりません。むしろプログラムの世界は選択肢が多すぎて何を使うかで悩む贅沢っぷりです。

ドラえもんも緊急事態で「あれでもない、これでもない」とポケットの中から何の道具を使うか悩むことがあるように、我々プログラマも何のモジュールを使うか、どのフレームワークを使うのかといったことで「あれでもない、これでもない」と悩みます。

実は、オブジェクト指向の世界は映画のようなSFの世界が舞台となっているのです。

このことに気がついたとき、僕は「オブジェクト指向は現実世界をそのままソフトウェアに表現する」は誤りなのではないか?と考え始めるようになりました。そんな疑問を抱きながら、僕は10年近い時間を消費してオブジェクト思考の理解を深めていきました。そして、オブジェクト指向の学習には理解の妨げとなる概念があることに気がついたのです!

それは、オブジェクト指向の世界に生命を持ち込むと混乱するということです。

いったいどういうことなのでしょうか。説明いたしましょう!


そもそも生命とは何か

3cycle.png

生命と生命でないものの区別とは一体どこにあるのでしょうか?一般的に動物は生物と呼ばれ、土や石のような動かないモノは物質と呼ばれます。

しかし、肉体も物質です。となると、生命とは一体なんでしょう?

それは「観測」「思考」「実行」の3つのサイクルを使って「物質に影響を与える物質」です。

このサイクルを持ち合わせているものを生命と呼び、プログラミングの世界でこのサイクルを持ち合わせているものは「プログラマ」しかいません。

コンピュータは生きていませんが、どんな物質よりも生命に近い存在と言えるでしょう。なぜならコンピュータは、生命と同じようにデータを「読取」「変換」「出力」するからです。これは生命特有の3サイクルに限りなく酷似しています。

しかしコンピュータは、人間のように自動的にアルゴリズムを生み出す「思考」を持ち合わせていません。コンピュータはプログラマの想定した通りに動くだけであり、生命とは程遠いのです。

オブジェクト指向で作成したオブジェクトやインスタンスをこの「生命」と勘違いしてしまうと、オブジェクト指向の世界を正しくイメージできなくなってしまいます。

それでは、なぜオブジェクト指向に生命を持ち込んではならないのでしょうか。


生命がモノを創る

モノを創るのは生命です。モノがモノを創ることはありません。

工場でモノがモノを作ることはあります。しかしこれは人間が効率よくモノを生産するために「モノを作るモノを創った」ということであり、根源的にモノを創るのは生命です。

オブジェクトにはモノを創る能力は無いため、オブジェクト指向の世界にモノ創りの能力のある生命を持ち込んではいけません。


人は生命を創れない

オブジェクト指向の世界はモノ創りの世界です。人の工作によって「生命」は創作できませんから、人間は生命を創ることができません。

何いってんだ!人間は子供を産むことができるんだぞ!と思うかもしれませんが、子作りはモノ創りではありません。もし子作りがモノ創りであるならば、産む前にアレコレ試行錯誤して自由なものを産めるはずです。しかし、そんなことはできません。

魚の養殖とかで作ってるよ?と思うかもしれませんが、これもモノ作りではありません。これは人が生命を閉じ込めて誕生のプロセスに介入したということであり、生命を人間がゼロから創り出したわけではありません。

人は生命を創れませんから、オブジェクト指向の世界に創ることのできない生命を持ち込んではいけません。


生命だけに意識がある

知らないの?人工知能っていうのがあるんだよ!プププw と思うかもしれません。しかし、人工知能に意識はありません。

そんなのわからないじゃん!自分以外のものに意識があるかなんて証明できないよ?とか言われると哲学の世界に突入して流石に困りますが、少なくとも人工知能は生命との相違点が多いです。生命は人工知能のように高速な計算をしたり、精度の高い記憶をしたり、知能を複製したりできません。そのため人工知能の意識は生命のソレとは異なるものであると解釈する方が得策と言えます。

どのみち、人類がコンピュータに意識を持たせることができたら、それはもはやプログラミングの常識が覆ることとなり、オブジェクト指向なんかどうでもよくなります。

先のことはわかりませんし現在、人間はコンピュータに意識を持たせることができていません。

オブジェクトは生命特有の意識を持ちませんので、オブジェクト指向の世界に意識を持った生命を持ち込んではいけません。


生命はスタンバらない

生命はロボットのように指示が与えられるまで固まったりしません。生命はリアルタイムに動き続けています。それは心臓の動きをとってもそうですし、精神活動をとっても睡眠中でさえ夢を見たり絶え間無く活動し続けています。

生命が固まるときとは、生命が生命でなくなるときであり、生命はロボットのように死んだようにスタンバイしたりしません。子供に「ここでじっとしてなさい!」と指示を出しても言う事を聞かないし、犬に「お座り!」と指示を出しても10分ともちません。

オブジェクト指向の世界で作ったDogインスタンスが生きた動物のようにウズウズして勝手に動き出したりするでしょうか?いいえ、そんなことはありません。Dogインスタンスは命令を受けるまで死んだようにじっとしています。いえ、もともと生きてはいないのです。

オブジェクトは指示が与えられるまでスタンバイできますが、生命はスタンバれませんのでオブジェクト指向の世界にスタンバれない生命を持ち込んではいけません。


生命は融通がきく

簡単な指示も守れないポンコツ生命ですが、生命が得意とすることがあります。

それは、生命は空気を読んで行動できるということです。人間はもちろん、犬だってご主人の顔色を伺って行動します。虫のような小さな生命は人間のように哲学したりしませんが、餌の場所を突き止めて仲間に伝達したり、あらゆる手段を使って逃げたり戦ったりと空気を読んで活動しています。

ロボットは転んで起きれなくなったり、例外が発生しているのに状況を判断できずに動き続けたりしますが、生命は例外が発生した時には「変だな」とか「やばいぞ!」とかの感情が沸き起こって適切な対処を取ることができます。

この空気を読むという行動から派生する行動の中に「メンテナンス」があります。昆虫が自分たちの巣をメンテナンスするように、プログラマもソフトウェアのメンテナンスを行います。プログラムはソフトウェアの異常を検知して伝達することはありますが、自動的に悪い箇所を探してメンテナンスしてくれたりはしません。

プログラミング言語には例外処理(try...catch)があるじゃないか!と思うかもしれませんが、結局これはプログラマが前もって想定していた例外を処理するだけのことです。

オブジェクトは空気を読んで活動できませんが、生命は空気を読んで活動できますのでオブジェクト指向に融通が利く生命を持ち込んではいけません。


生命には明確な規格がない

ロボットのような人間が創ったモノはパーツを気軽に交換することができますが、生命はパーツを気軽に交換したりできません。

よく考えてみると義手のような交換可能なモノもあります。しかし義手を装着して生活している人は珍しく、また他人の義手を自分の腕にはめて使ったりすることはできません。

昔、人がまだ体の中に何が入っているのか知らなかった頃、体を切り開いて中身を確認した人がいました。その人は、ただ認識しやすかったり、手に取りやすかったりといった理由で、臓器に名前をつけていきました。人が知らないものを知っていくということは素晴らしいことです。しかし、臓器に命名したからといってそれが交換可能なパーツになるわけではありません。

これは生命には交換可能な規格というものが無いということです。もちろん一切交換できないわけではありませんが、交換できるようには作られいません。

人は利便性や拡張性を向上させる理由で規格を作ります。そしてオブジェクト指向のインターフェースはまさに規格と言えます。

生命には明確な規格がありませんが、オブジェクトには明確な規格がありますのでオブジェクト指向の世界に明確な規格を持たない生命を持ち込んではいけません。


生命は出産する

生命は出産によってインスタンス生成しますが、生命のようにインスタンスがインスタンスを生成する設計方法はあまり行われません。

全くないとは言えませんが、もしそのような出産設計が必要となった場合は、出産と考えるより、ロボットを生成できるロボットをイメージする方が混乱がありません。

オブジェクト指向でインスタンスが生成されるプロセスは、よくタイ焼き機を使って解説されることがあります。もしもオブジェクトが生命だったら、この生成プロセスをどう解釈すれば良いのでしょうか?いろんな形の型にはめてクッキーを作るみたいに生命を作る方法なんて、僕は聞いたことも見たこともありません。

オブジェクト指向ではnewを使ってインスタンスを生成しますが、もしnewが出産だとするならば、メイン関数でnewしたインスタンスは誰が出産したのでしょう?神が出産したとでも言うのでしょうか。

また、プログラマはnewを調理前に食材を用意する要領で使ったりするため、いちいち何かを生成する度に出産を連想するのは奇妙です。

生命は出産しますが、newを出産と考えるのは無理がありますのでオブジェクト指向の世界に出産する生命を持ち込んではいけません。


生命にはコンストラクタが存在しない

生命は小さな細胞が分裂を繰り返して成長することで誕生しますが、ロボットはパーツを組み立てることで完成します。

コンストラクタはインスタンス生成時に必要なものを渡すことができる機能です。これは、工場などでロボット生産をする時にアームなどの必要なパーツを明け渡して作ることに置き換えて考えることができます。しかし、生命を誕生させる時に細胞にアームを渡すなんて話聞いたことがありません。

ある意味、精子の中に含まれる遺伝子情報がコンストラクタに渡すパラメータであると考えることができるかもしれません。しかしこのように思考することは、もはや「全てはデータである」と言っているようなものであり、オブジェクト指向のオブジェクトはどこに行ってしまったのか、という話になってしまいます。

生命にはコンストラクタが存在しませんので、オブジェクト指向に生命を持ち込んではいけません。


まとめ

ここまで、オブジェクト指向に生命を持ち込んではいけない理由を解説させていただきました。

「オブジェクト指向は現実世界をそのままソフトウェアに表現する」と言われますが、オブジェクト指向の世界は現実でできないことができ、生命は存在しない世界であると考えた方が自然です。

オブジェクト指向を学び始めた時、このことを知らされていないため「なるほどなぁ!オブジェクト指向は現実世界をそのままソフトウェアに表現するのかぁ!」と誰もが誤った考えを鵜呑みにして混乱に陥ります。

ソフトウェア設計は複雑です。その複雑性を取り払うには、ソフトウェアの中身を明確にイメージできるようになることが大切です。

オブジェクト指向の世界は「生命のいないSF仮想世界」です。そのため、オブジェクト指向の世界は「SFロボットワールド」であると考えるのがオススメです。

SFロボットワールドは、コンピュータの中に存在する「真のオブジェクト指向の世界」です。我々はテキストエディタを使ってSFロボットワールドに接触できます。そしてプログラマはSFロボットワールド唯一の生命であり、国王なのです!

SFロボットワールドは現実世界とは異なる法則があるため、この法則をよく理解することはソフトウェア設計の混乱を避けることに繋がります。

SFロボットワールドは高速で、モノの大きさの概念が無く、分身を所有でき、生命が存在しません。

この中で最も注意しなければならないのが「生命が存在しない」ということです。コンピュータが高速であることは誰もが知っているし、分身を所有できるということはポインタの概念を学んでいれば皆様もなんとなく感じているはずです。

しかし生命が存在しないという考え方は、オブジェクト指向の説明にDogやCat、Animalを使った解説がなされることが多いので、なかなか気がつくことができません。

きっとこの「SFロボットワールド思考法」を使えば、オブジェクト指向の誤解がとけ、オブジェクト指向を感じながらプログラミングできるようになるはずです。

この記事に対する貴重な反論記事@matari様に頂きました!こちらも合わせて読んでいただけると更なるオブジェクト指向の理解が得られると思います!