#既存の説明では、ぜんぜん意味が分からない!
現代的なプログラミングにおいて、「オブジェクト指向」(英語名「object-oriented(OO)」)が重要な技術であるのは、言うまでもありません。
もしかすると「そんなの今さら常識」と思うかもしれませんが、しかし本当の意味で理解して使われている場合は、じつは少ないのではないかと思います。
たんにJavaやRubyなどのOO言語で書くだけで、自動的にOOが実現するわけではありません。実際はオブジェクト指向になっていない場合がかなり多いです。
しかしその一方で、「オブジェクト指向」について、本当の初心者に分かりやすい解説というのが、ほとんど見あたりません。
「犬がワンで、猫がニャー」みたいな、ワンニャー式のよくある解説を読んでも、
「オブジェクト指向とは何なのか」、「何が良いのか」、「何がしたいのか」、「なぜ採用するのか」、「複雑になってしまうのではないか」、「それまで(構造化)と何が違うのか」、「何をすればOOなのか」、「何がOOにとって一番大事なのか」、「どこからどこまでがOOなのか」、
……などなど、疑問が際限なく湧いてくると思います。
じつは昔は私自身も、オブジェクト指向がいったい何なのか、さっぱり分かりませんでした。今では逆にオブジェクト指向なしに組みたくないほど、身近な存在になりましたが。当時は分かりにくい説明にたいへん不満でした。
そこで本記事(連載を予定)では、分かりやすさを最重視して、割り切って説明します。分かりやすく、分かりやすく、とにかくそれを最優先に追求しています。「くわしく」より「分かりやすく」に振っていきます。ですので、「分かりやすい嘘」もためらわずに採用します。
もちろん、いろいろな立場があり、割り切れない難しい部分もあるのは百も承知です。が、「そんな単純じゃない」と言って、「あれもこれも」と概念を出すと、分かりにくくなってしまいます。その点をご了承の上、お読みください。
前置きが長くなりましたが、それでは説明していきましょう。
#オブジェクト指向とは何なのか? 何がしたいのか?
オブジェクト指向(プログラミング)というのは、「オブジェクト」を単位にしてプログラミングする技法です。
オブジェクトを単位にすると何が違うのかというと、「カプセル化」されたプログラムにすることができます。
そもそも「オブジェクト」とは何かは、次回(以降)説明しますが、ここでは「オブジェクト=カプセル」とかんたんに理解しておきます。
かつて、OOが普及する前の「構造化技法」の時代でも、「モジュール化」はされていましたが、カプセル化としてはまだ不完全でした。
では「カプセル化」すると何が良いのか。それを一言でいうと、「変更容易性」です。プログラムの開発が完成した後で変更しやすくなります。派生的に保守性、拡張性、再利用性(の向上)なども挙げられます。
変更が容易だと何が良いかというと、保守コストが減ります。一般的に商業プログラムにおいては、開発費用より保守費用の方が大きくなりがちなので、企業としては経費削減の意味があります。
また、たとえ個人開発者でひとりで組んでいても、ある程度まで規模が大きくなると、保守する手間というのは無視できないので、その場合に採用する意味はあると思います。逆に、変更の予定がない小規模の書き捨てプログラムでは、OOの効果を発揮できません。
この点、「じゃんけんプログラム」みたいな単純なサンプルでは、OOの良さが伝わりません。構造化で書いても大差ないし、むしろそっちの方が簡明です。まあ書籍などは紙幅の関係で仕様がないですが。
「定期的にカードが追加されていき、カードによってゲームルールも微妙に変化していくTCG風カードゲーム」のような実際の複雑なプログラムで、OOの本領を発揮します。
こうしたメリットの一方で、OOにデメリットはないでしょうか? たとえば、OOだと複雑になってしまわないか?
複雑にはなるでしょう。しかし、ミクロレベルで多少複雑になっても、マクロレベルでは単純化できるはずです。また、大規模な開発だと、開発しながら保守するような面がありますので、開発もしやすくなる側面があります。
100行レベルで見ると複雑になっても、100「万」行レベルで見ると、かえって単純になるのです。まあ100万行は極端に思うかもしれませんが、5千行から1万行くらいで、コードの理解しやすさに明確な差が出てきます。
OOは「都市計画」のようなもので、1万行、100万行の上空から鳥瞰的に見ると、整理されているのです。「木を見て森を見ず」になると、OOの良さが見えてきません。
コードが多少複雑になっても、変更容易なメリットの方が大きい、と判断したときに採用すれば良いのです。
ただ、組み込みなど、非常に小さなオーバーヘッドが問題になる環境では、採用しない場合もあります。
まとめると、何がしたいかというと、プログラムの変更を容易にしたいのです。
だから、それをカプセル化で実現するため、オブジェクト指向を使うのです。
イメージしやすいように、シナリオを描いてみます。
プログラムを組んで完成したところを想像してください。
次に、完成後に変更するところを想像してください。
プログラミングの経験があれば、ジェンガ(積木)が崩れるように、
カオスになっていくところが想像できると思います。
仕様変更はだれしも嫌なものです。なければない方が良いです。
しかし、ビジネス上の理由などで、せざるをえない場合があります。
たとえば、消費税や年号、法律の改正といった不可避の場合。
あるいは、利用しているライブラリやサービスのAPI変更の場合とか。
商業的なプログラムは、競争力などの関係で規模が大きくなりがちですが、
規模が大きいと変更しにくくなるし、しかも変更が不可避の場合があります。
変化に対応できなくて生き残れない、というケースもあるでしょう。
しかし、オブジェクト指向で組んであると、相対的に変更に強いのです。
これは「うさぎと亀」のたとえ話のようなもので、
開発が多少難しくなっても、保守のターンで取り戻せるのです。
カプセル化のカプセルは亀の甲羅のようなもので、
書く速度は遅くなりますが、外敵(バグ)から本体(コード)を守ります。
OOは「ドジでのろまな亀」ですが、長い目で見れば安定しているのです。
#FAQ形式で簡易まとめ
さて、ここまでの整理として、冒頭の疑問をFAQ形式で、かんたんにまとめ直してみましょう。
- Q. 「オブジェクト指向とは何なのか」
- A. ――オブジェクトを単位にカプセル化する技法です
- Q. 「何が良いのか」
- A. ――変更が容易になります
- Q. 「何がしたいのか」
- A. ――(完成後も)変更を容易にしたいのです
- Q. 「なぜ採用するのか」
- A. ――変更を容易にすると、保守コストを減らせます
- Q. 「複雑になってしまうのではないか」
- A. ――なりますが、メリットの方が大きい場合に採用します
- Q. 「それまで(構造化)と何が違うのか」
- A. ――モジュール化とカプセル化の違いです
- Q. 「何をすればOOなのか」
- A. ――カプセル化すればOOです
- Q. 「何がOOにとって一番大事なのか」
- A. ――(ここでの立場では)カプセル化です
- Q. 「どこからどこまでがOOなのか」
- A. ――オブジェクトやカプセル化が関係する範囲です
#新たな疑問と、この先の予定について
ここまで読んで、こういう疑問が湧いてくるかもしれません。
オブジェクト指向の本質がカプセル化だとして、
なぜカプセル化すると変更が容易になるのか?
また、具体的にどのように書けば、
カプセル化されたプログラムになるのか?
それは次回(以降)に説明します。
今回は「なぜ」「Why」だけ説明しました。
一度に詰め込もうとすると分かりにくくなるので、
「どうやって」「How」は後回しにします。
本記事(連載)では、分かりやすさを最優先しているため、
まるで亀の歩みのように、説明のペースが異様に遅いです。
しかし、分かったつもりのうさぎを、
最後には追い抜ける地点まで行けるはずです。乞うご期待。
#参照
今回書いたことは、たんなる私ひとりの思いつきではありません。
多数派の考え方ではないかもしれませんが、『オブジェクト指向のこころ』などオブジェクト指向関連の書籍で、すでに先人が主張しています。
またたとえば、開発費より保守費が高いこと、よって変更を容易に組むべきということについては、「XP(エクストリーム・プログラミング)」の提唱で有名なケント・ベック氏も、『実装パターン』で指摘しています。
ただし『実装パターン』については、オブジェクト指向だけに限定せず、プログラミング全体の原理原則を追求しているのが、著者の意図だろうとは思います。
そしてまた、それらの著者の思考を忠実に伝えることまでは意図しておらず、最終的には私の個人的な考えであることもお断りしておきます。
今言及した参考文献をあらためて挙げておきます。
なお、記事中の画像は素材サイト「足成」のものを利用しました。