オブジェクト指向を少し理解するために

## はじめに
オブジェクト指向について何となくは知っているつもりだったが、いざコードを書くとなると「どう書けばいいか分からん」となったので、初心者にも分かりやすくオブジェクト指向について書かれていそうな、**「[オブジェクト指向でなぜつくるのか 第2版](https://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-ebook/dp/B00ISP0QB2)」**を読んでみた。
**※ 基本的に自分の理解が曖昧な部分を中心にまとめている**

## 1. オブジェクト指向はソフトウェア開発を楽にする技術

- オブジェクト指向とは、モノ指向・モノ中心として見る考え方・概念
- オブジェクト指向が普及する前は、「機能中心」の開発手法が主流だった（機能中心だと、後々仕様変更や機能追加があった場合修正しにくい）
- **「用語の洪水、比喩の乱用、なんでもオブジェクト症候群」この3つの混乱しやすい要因を排除することが大切**

![oopl1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298333/41ec5309-8ef9-93f4-d99b-028b64e7bb50.png)

なんでもオブジェクトで考えてしまうことを、この章では**「なんでもオブジェクト症候群」**と言っているが、実際プログラムを書き初めたての頃、オブジェクト指向の例え話を聞いた際に、「現実世界のモノは、なんでもプログラムで表現できるのでは？」と思っていたので、この考えを改め直さないなと感じた

- **OOPL**：オブジェクト指向プログラミング言語
- **OOP**：OOPLを使ってプログラミングをすること


## 2. オブジェクト指向と現実世界は似て非なるもの

- **ポリモーフィズム**は類似したクラスに対してのメッセージの送り方を共通化する仕組み。同名のメソッドで異なる挙動を実現すること。メリットとしては、どのクラスのインスタンスかを意識しなくてもよくなる

1章でも出てきた**「なんでもオブジェクト症候群」**。オブジェクト指向では最初にクラスがあり、そこから具体的なモノ（インスタンス）が生まれる。一方、現実世界では先に具体的なモノ（インスタンス）があって、それを見る側が勝手に分類（クラス）するという違いがある。他の違いに関しても本書で書かれていた

## 3. OOPを理解する近道はプログラミング言語の歴史にあり

![oopl2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298333/5495a0ad-349d-0ffd-78f8-6d082557b7c1.png)

- プログラミング言語の進化**（機械語 → アセンブリ言語 → 高級言語 → 構造化言語 → OOPL）**
- **構造化プログラミング**

>構造化プログラミングとは、コンピュータプログラムの開発や理解、修正を円滑に行えるよう、プログラムを整理された構造の組み合わせによって構成すること。一般的には順接、反復、分岐の三つの制御構造によって処理の流れを記述することであると理解されている。
引用：[構造化プログラミングとは - IT用語辞典 e-Words](http://e-words.jp/w/%E6%A7%8B%E9%80%A0%E5%8C%96%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0.html)

構造化プログラミングはGOTO文の廃止を主張
**GOTO文**：任意のラベルに無条件で分岐する命令

- **サブルーチン**は複数の場所に現れる命令を1つにまとめ、他の処理から呼び出して実行できるようにしたもの

- 複数の箇所に現れる命令をひとまとめにするだけでは、保守性を高めるためには不十分だとこの本では書かれていた。では何をすれば保守性を高めることができるのか？🤔
→ **メインルーチンとサブルーチンで共有する情報を少なくする**。ここでいう共有する情報というのは**グローバル変数**のこと

- なんでグローバル変数を減らす必要があるのか？🤔
→ グローバル変数はどこからでもアクセスできてしまう。そのため、仮にエラー発生時や改修作業が入った時に、コードを追うのが大変



## 4. OOPは無駄を省いて整理整頓するプログラミング技術

![oopl3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298333/7df446f2-d447-220a-0b23-aa4afb4ba3fd.png)

- 今までのプログラミング言語にはなかったOOPLの仕組みが3章で触れた**「クラス」「継承」「ポリモーフィズム」**
- それぞれの仕組みについて
    - **クラス**：サブルーチン（メソッド）と変数（インスタンス変数）を1つにまとめて部品を作る仕組み。「まとめて、隠して、たくさん作る」
    - **継承**：クラスの共通部分を別のクラスにまとめる仕組み
    - **ポリモーフィズム**：サブルーチンを呼び出す側のロジックを一本化する仕組み
- 比較的新しい言語では「クラス」「継承」「ポリモーフィズム」の他に、**「パッケージ」「例外」「ガベージコレクション」**の機能がある


## 5. メモリの仕組みの理解はプログラマのたしなみ

- **中間コード方式**：コンパイラを使ってソースコードを中間コードに変換し、そのコードを専用インタプリタによって解釈して実行する。インタプリタ方式とコンパイラ方式の良いとこ取り

![oopl4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298333/80fc6606-6360-6738-9c38-599b9240a88b.png)

- メモリ領域は「静的領域」「ヒープ領域」「スタック領域」の3つに分けて管理
    - **静的領域**：プログラム開始時に確保。プログラムが終了するまで配置が固定される領域。格納される情報としては、グローバル変数や実行コード
    - **ヒープ領域**：プログラム実行時に動的に確保するための領域。格納される情報は任意
    - **スタック領域**：スレッド制御のために使う領域。格納される情報は呼び出したサブルーチンの引数やローカル変数、戻り先
- **「OOPLを使って書いたプログラムは、有限のメモリ領域であるヒープ領域を大量に使って動くこと」**を認識しておく必要がある
- 変数にはインスタンスそのものでなく、**ポインタ（場所を示す情報）**が格納される

## 6. OOPがもたらしたソフトウェアとアイデアの再利用
デザインパターンが一般的に知られるようになったのは、「デザインパターン」という本がきっかけ。4人の技術者がまとめたもので、**GoF**（4人組）と呼ばれている

デザインパターンについて調べていたところ以下のサイトに詳しくまとめられていたので、時間がある際にゆっくり読みたい
[デザインパターン | TECHSCORE(テックスコア)](https://www.techscore.com/tech/DesignPattern/index.html/)

## 7. 汎用の整理術に化けたオブジェクト指向

特になし

## 8. UMLは形のないソフトウェアを見る道具

- **UML**：ソフトウェアの機能や内部構造を図式表現するための統一記法
    - OOPのプログラムの構造や動作を表現する（クラス図とかシーケンス図とかコミュニケーション図）
    - 汎用の整理術としての成果物を表現する
    - オブジェクト指向で表現できない情報を表現する

## 9. 現実世界とソフトウェアのギャップを埋めるモデリング

特になし

## 10. 擬人化して役割分担させるオブジェクト指向設計

- OOPを使って書いたメソッドは数行程度、ときには1行だけになることも珍しくない

## 11. オブジェクト指向から生まれたアジャイル開発とTDD

- 反復型開発プロセスとして、**XP**や**RUP（ラショナル・ソフトウェア社が開発・販売している商用の開発プロセス）**がある

## 12. オブジェクト指向を使いこなそう

- オブジェクト指向の次に来る技術として、アスペクト指向やエージェント指向、SOA（サービス指向）などが注目を集めた
    - **アスペクト指向**：共通処理を分離して記述することにより、柔軟性をより高める仕組み
    - **エージェント指向**：能動的に活動するエージェントを中心にソフトウェアを作り上げる考え方
    - **SOA（サービス指向）**；個々の機能を提供する部品の集まりと見なす考え方

## 13. 関数型言語でなぜつくるのか

- **純関数型言語**：関数型言語の仕組みだけを持つ。逆に従来の言語の仕組みを併せ持つ言語を非純粋型関数型言語という
- オブジェクト指向言語では、クラスを使ってプログラムを組み上げるが、関数型言語では関数を使ってプログラムを組み上げる
- 命令型言語と関数型言語の違いとして、命令型言語では、メモリ領域に格納されたデータを読み書きしながらプログラムを実現する。一方関数型言語は、個々の式を次々と評価し、そこで得た値を利用する別の式を評価していくことによってプログラムを実現する