オブジェクト指向プログラミングとは何なのか？

## なぜ今更このテーマなのか
今日、ソフトウェア開発を行うにあたって「オブジェクト指向プログラミング」というワードは避けては通れないキーワードである一方で「そもそもオブジェクト指向プログラミングって何者なのか」ということをいい加減ハッキリさせるために勉強してみました。

## 自己紹介
1994年1月10日生まれ。Webアプリケーションデベロッパーのたまご。2015年6月〜7月の1ヶ月間TECH:CAMPに通い、インターネットメディア事業を開発・運営するスタートアップへインターン入社。目白大学人間福祉学科4年を2015年10月に休学。これまで取り扱ってきた技術は以下の通り。
#### OS
***
- MacOS
- CentOS

#### アプリケーション開発
*** 
- Ruby
- Ruby on Rails
- HTML
- Slim
- CSS

#### インフラ
***
- Nginx
- さくらクラウド

#### データストア
***
- MySQL

## 対象読者
- オブジェクト指向が何者か知りたい人
- オブジェクト指向に興味のあるプログラミング初学者〜中級者

## そもそもオブジェクト指向プログラミングとは何なのか
今回オブジェクト指向が何者かを知るために以下の書籍とWikipediaを一読したところ、オブジェクト指向プログラミング以外のプログラミング手法を知ることが一番だと感じた。

[オブジェクト指向でなぜつくるのか 第2版 | Amazon.co.jp](http://www.amazon.co.jp/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%81%A7%E3%81%AA%E3%81%9C%E3%81%A4%E3%81%8F%E3%82%8B%E3%81%AE%E3%81%8B-%E7%AC%AC2%E7%89%88-%E5%B9%B3%E6%BE%A4-%E7%AB%A0/dp/4822284654)
[オブジェクト指向プログラミング | Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)

## オブジェクト指向プログラミング以外のプログラミングとは何か
これについては9割方プログラミングの歴史を振り返ることになる。具体的にはプログラミングは以下のような歴史を辿ってきたとされる。

#### 機械語
> コンピュータのCPUで直接実行される一連の命令である。手作業で一つ一つのビットを管理したり、数字で表されたアドレスや定数を計算したりするのは非常に骨の折れる作業であり、ミスが生じる可能性も高い。それゆえ、今日では、極めて厳格な最適化やデバッグが必要とされる場合をのぞいては滅多に行われることはない。

#### 高級言語
> 高級言語とは、プログラミング言語のうち、より自然語に近く、人間にとって理解しやすい構文や概念を持った言語の総称である。高級言語は、主に英単語や記号などを組み合わせて命令を記述し、コンパイラやインタープリタなどで機械語に変換され、実行される。

#### 構造化プログラミング
- 順次実行、反復、分岐を主な特徴として持つプログラミング。GOTO文で煩雑になりがちだったプログラムがループ処理や条件分岐による制御構造を持つことで整理されたものとなった。

#### オブジェクト指向プログラミング
- 主にクラス、ポリモーフィズム、継承がオブジェクト指向を表現する概念とされる。それまで機能ベースだったプログラムを部品単位でプログラミングすることで保守性や再利用性を高くしようとする思想。ハードウェアの進化によってソフトウェアも大規模なものが開発されるようになり、保守性・再利用性の高いプログラミングが必要になったことがきっかけで浸透してきた。


## つまりオブジェクト指向プログラミングとは何か
以上の歴史を見てもらえれば分かる通り、オブジェクト指向プログラミングとはつまり大規模なソフトウェア開発にも耐えうる開発手法なのだ。機械語や高級言語レベルでは現代のソフトウェア開発には耐え難いのは明らかであり、構造化プログラミングでも機能ベースの開発では急な仕様変更や機能追加の際に書き換えの規模が大きくなってしまったり、同じような記述を繰り返すことが多く、一方でハードウェアは日々進化し、開発するソフトウェアの規模も大きく複雑になっていく。そこでオブジェクト指向という考えが浸透し、クラスやポリモーフィズム、継承などの機能も浸透していったとされる。

## オブジェクト指向は今日のソフトウェア開発にどのような恩恵を与えているか
オブジェクト指向は今日のソフトウェア開発において以下のような恩恵をもたらしていると考えられる。
- **保守性・再利用性が高くなる**
- **ライブラリ・フレームワークといったパッケージ群を使用することができる**
- **テストが楽になる**

保守性・再利用性が高くなるというのは、そもそもそれらを目的として生まれた思想であるので当然である。具体的にこれらはクラス、ポリモーフィズム、継承といった仕組みを活用することで実現している。オブジェクト指向が浸透する以前は、共通ロジックをまとめる仕組みはサブルーチンと呼ばれる関数のみであったが、オブジェクト指向プログラミングではクラスに共通ロジックをまとめることができる他、変数もまとめることができるのでグローバル変数が乱立し、変数名が競合したり予期せぬ場所から参照・変更されるといったことが発生しづらくなる。ポリモーフィズムや継承ではプログラムの重複を減らすことで保守性・再利用性を高めている。

ライブラリ・フレームワークといったパッケージ群は恐らくオブジェクト指向でなければ誕生していなかったんだろう。開発するソフトウェアがコマースだろうとメディアだろうとRailsは使えるし、kaminariやdeviseといったgemも使える。(というかRails自体gem)これはクラス、ポリモーフィズム、継承といった仕組みをうまく使い、オブジェクト指向に則って設計・プログラムされているからだろう。機能ベースのプログラミングでは実現できていないと思う。

また、保守性・再利用性が高まるということは1ブロックあたりのプログラムが簡潔であるとも言えるはずだ。これは結果としてテストがしやすいという恩恵ももたらしている。

## まとめ・考察
以上の通り、オブジェクト指向プログラミングを学ぼうと思ってみたがその実態は時代の流れに揉まれ浸透したソフトウェア開発の思想であった。オブジェクト指向で開発するために「こうすると良い」という実践的なテクニックについては本書ではほとんど触れられていなかったが、オブジェクト指向の本質に触れることができたと感じており、実際どのようにプログラミングするかは言語仕様やフレームワークによって別途学べば良いと思えた。しかし本書を読んだところRuby, Railsはオブジェクト指向が何たるかを知らなくてもクラスやポリモーフィズム、継承といった仕組みを自然と使えるよう設計されていると感じられ、普段当たり前のように使っていながら凄いと思った。一方でアプリケーションの規模が大きくなったときに自身で新たにクラスを作ったりモジュールを作ったり、継承等の仕組みをうまく使いこなし、オブジェクト指向の思想に則ってエレガントなコードを書けるかとなると、また一段ハードルが上がるだろうと感じられた。

## おまけ・書評
オブジェクト指向については以下の書籍に定評があるそうだが本書も初学者〜中級者には良書だと感じられた。というのも、クラスから生成されたインスタンスではメモリの使い方にも特徴があり、そのあたりにも触れられている他、現在注目を集めている関数型プログラミングについても末尾で触れられており、非常に勉強になった。ちなみに関数型プログラミングの特徴として、「全ての式が返り値を持つ」というのがあるのだがRubyも同じ仕組みを有しており、Rubyってやはり最先端やなあと思いますます好きになりました。

[アジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の神髄と匠の技 | Amazon.co.jp](http://www.amazon.co.jp/%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%96%8B%E7%99%BA%E3%81%AE%E5%A5%A5%E7%BE%A9-%E7%AC%AC2%E7%89%88-%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E9%96%8B%E7%99%BA%E3%81%AE%E7%A5%9E%E9%AB%84%E3%81%A8%E5%8C%A0%E3%81%AE%E6%8A%80-%E3%83%AD%E3%83%90%E3%83%BC%E3%83%88%E3%83%BBC%E3%83%BB%E3%83%9E%E3%83%BC%E3%83%81%E3%83%B3/dp/4797347783)