仕事上JavaやC#といったオブジェクト指向の言語を使用したシステムの設計や実装の開発経験者と話をする機会が最近多くなって気づいたのですが、バリバリのオブジェクト指向言語をお仕事として書いている人でもかなり初歩の段階でつまづいている人が大多数だということです。
しかも一年未満の初心者ばかりではなく5年以上の実務経験があったり、簡単ではないプログラムの資格を持っていたり、月100万以上の単価だったりと、決して初心者と呼べないエンジニアがあれ?というほど初歩の段階でつまずいているということです。
また、Qiitaの記事でオブジェクト指向の解説の記事を見ても誤解が多いなと感じます。
そんなにも世間のオブジェクト指向の理解度が高くないのはなぜなのか?
その原因は様々だと思いますが、その原因一つ一つを考えるときりがありません。なので今回はその原因を、誰もが最初はお世話になるであろう入門者向け教材にあるとの仮定一つに絞って推察していきます。
オブジェクト指向入門教材
オブジェクト指向「オブジェクト指向入門」と銘打っている本や動画を見ると、
オブジェクト指向3大要素(カプセル化、継承、ポリモーフィズム)について一通り解説されていて、学習する上で一見何も問題ないように思えます。
でも世間のオブジェクト指向の理解度はあまり高くないのはなぜなのか? それを意識して見ているうちにある違和感に気づきました。
<違和感>抽象化の解説が薄い
オブジェクト指向の入門教材でよく目にするのがCar(車)クラスです。
これにいろいろなフィールドやメソッドを定義し、それらを実装していく過程でオブジェクト指向の考えの一部を学習していくというものです。
その中で作られる車クラスの例が以下です。
車クラスの擬似コード
class Car
private name // フィールド
public Car(name) // コンストラクタ
name = name
public go() // パブリックメソッド
print name+"が走っています" //標準出力
コンストラクタで機種名を定義し、goメソッドを実行すると標準出力に「走っています」的な文を出力するというクラスですが、これと似たようなものが入門教材では比較的よく見られます。
このクラスを色々ゴニョゴニョしてオブジェクト指向3大要素(カプセル化、継承、ポリモーフィズム)の学習をしていくのですが、この時点で違和感を感じました。
そもそも現実社会の車というものは、走れメソッドを実行させると標準出力に"走っています"という文を出力する機械ではありません。
主に鉄から出来た無数の精密な部品からできていて、それらが素人には到底組み立てることが出来ないほど複雑に組み合わされています。
そして、ガソリンを入れ、ブレーキを踏みながらキーを回し、ギアを入れてアクセルを踏むとガソリンと空気の混合物がエンジンで燃焼され、そのエネルギーがタイヤの回転力に上手く伝わって物理的に移動する機械です。
それをオブジェクト指向入門書では、車は現実世界の車ではなく、オブジェクト指向3大要素の学習のために適した概念としての「車」という存在になっています。
その過程が抽象化というオブジェクト指向において重要なプロセスなのですが、そのプロセスがすっぽりと抜け落ちているのです。(もしくは数行の簡単な解説で終わっている)
そしてそのままカプセル化やポリモーフィズムといったものの学習に移っていくのですが、その過程でJavaなどの言語仕様も同時に学習し、ある程度自分でコードが書けるようになっていきます。
そうするとJavaのコーディングができるという成功体験をオブジェクト指向を理解したという誤解を生み、その後の学習プランが言語仕様の理解やテクニック、資格の取得などに偏り、本質的なオブジェクト指向を理解しようとする学習の方向から遠ざかってしまうのでは?という解釈です。
実際、抽象化の誤解が一番多いように思えます。また、オブジェクト指向を全く理解していなくても表面上動くシステムは一応作ることは可能だということがオブジェクト指向の学習を妨げているさらなる要因なのかもしれません。
まとめ
オブジェクト指向入門用の資料は抽象化の解説があまり丁寧にされていない資料が多い。
入門書も実務でも、オブジェクト指向の理解度の向上を必須としないという環境がエンジニアのオブジェクト指向の学習の優先度を下げている。
その結果が、オブジェクト指向の言語を扱っているエンジニアの理解度が高くない原因なのではという推察。