オブジェクト指向でなぜ作るのか？を読んでみて、自分なりのまとめ

# 参考文献
[オブジェクト指向でなぜ作るのか？amazonのリンク](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/dp/4822284654)
~~今ならkindle unlimitedで読めます！！~~

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

## オブジェクト指向を提唱した人の発言
**未来を予測する最善の方法は、それを発明することである**

## Q.なぜオブジェクト指向でソフトウェアを作るの？
A.**ソフトウェアを楽に作りたいから！**

## OOP
オブジェクト指向はOOP（object oriented programming)

オブジェクト指向はソフトウェアの**保守や再利用をしやすくすることを目的とした技術**
以前は「機能中心」の開発手法が主流だった。それだと変更に弱い

## 部品の再利用
再利用部品群のことを**クラスライブラリ**や**フレームワーク**という

再利用する時に利用されるお決まりの設計パターンが**デザインパターン**

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

余談：トレンドの言葉は「バズワード」という。バズるの語源だったりする。

クラスは**種類**
インスタンスは**具体的なモノ**

インスタンスにメソッドを呼び出させることを、
仕事を頼む様子に似てることから**メッセージパッシング**と呼ぶ

## ポリモーフィズム
日本語では「多様性」や「多相性」という

類似したクラスに対するメッセージの送り方を共通にする仕組み。
**相手が具体的にどのクラスのインスタンスであるかを意識せずにメッセージを送れる仕組み**

動物クラスを作成して、それを継承した犬、人間、カラスクラスを作る。
それぞれにcryメソッドを定義する。
呼び出す側は何のクラスのインスタンスか気にせずに、
**cryメソッドを実行するだけでそれぞれのクラスのcryメソッドが出力される。**

## 継承
**モノの種類の共通点と相違点を、体系的に整理する仕組み**

## オブジェクト指向と現実世界は似て非なるもの
**現実世界の人やモノはクラスから作らない**
子犬が生まれる時は、雄と雌が仲良くなった結果。
あらかじめ定義された犬クラスから作るわけじゃない。

人間も、会社に行くときは「社員」。打ち合わせする時は「技術者」。家では「父親」みたいに、状況によって分類（クラス）が異なる。

**インスタンスは唯一のクラスに帰属する。**クラスは一個しか持たない。
つまり、**他のクラスに鞍替えできない。**
赤ちゃんクラスでインスタンスを作ったら、一生赤ちゃんクラスのまま。
でも、現実世界は時間が経てば若者や中年になる。

プログラムはcryメソッドみたいに「泣け」っていう命令通りに動くけど、
**人間は命令どおりに必ず動くわけじゃない。**

しかも、プログラムの場合、**すべての行動をあらかじめ定義しないと何も出来ない。**
そして、メッセージパッシングでメソッドを呼び出すことで物事が動く。

こういった点から、**オブジェクト指向と現実世界は似て非なるもの**

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

昔は`A14001`みたいな機械語を理解できる人しかエンジニアになれなかった。

次に、アセンブリ言語が生まれた。`MOV AD, XD`みたいな記述をする。
でもこれじゃまだ分かりにくい。
そして、現代で使われる`Z=X+Y`みたいな高級言語が生まれた。
人間にも理解できるやつ。

## 構造化プログラミングが提案される
正しく動作するプログラムを作るには、**わかりやすい構造にすることが重要**という考え。

プログラムを分かりにくくする元凶の**GOTO文**を廃止して、下記の3つの構造だけで表現する。
・順次進行（上から処理）
・条件分岐（if文）
・繰り返し（for文）

## サブルーチンの独立性を高めろ
グローバル変数を参照すると、変更があった時にどこで変更されてるか追いにくい。
数千行のコードだとなおさら。
しかも昔はビルドがめっちゃ遅かった。余裕で数時間かかる。

その問題を解消するために、**ローカル変数**と**引数の値渡し**が生まれた！

## 構造化では解決できなかった問題
・グローバル変数問題
・貧弱な再利用
これをオブジェクト指向で解決する！

## 処理をライブラリに切り分ける
プログラミングに必要な機能を言語仕様で提供しないで、
rubyみたいに組み込みライブラリにして切り分けたこと（Stringとか）
これで、言語コンパイラとかを改良しなくても、言語レベルの機能追加ができるようになった！

アセンブラのコンパイラも、昔は機械語で書かれてた。
それをアセンブラに書き直した。鶏か卵が先か問題のやつ。

# 4章　OOPは無駄を省いて整理整頓するプログラミング技術
Tips：サブルーチン＝メソッドと読み替えておk

## まとめる
一つのやりたい処理のためにクラスをまとめる。
そうすると、メソッド名を短く出来たり色々恩恵がある！

## 隠す
変数をprivateにすることで、内部のメソッドからしか参照できないようにする。
メソッドはpublicにして、インスタンスから参照できるようにする

## たくさん作る
インスタンスごとに違った情報を持てる。
一般的なアプリケーションは、同種の情報を複数同時に扱うことがよくあるから、この仕組はめっちゃ強力。
これがないと、配列を使って必要な数だけ変数領域を確保しないといけなかったりして、そうするとその分メソッドが複雑になる。

**必要な分だけ作る**っていう柔軟性を持った仕組みは、従来のプログラミング言語にはなかった！

## インスタンス変数は、「仲間内だけのグローバル変数」

## ポリモーフィズム

### 共通サブルーチン
**クラスメソッドと同じ認識で良さそう**
呼び出す側が増えても、呼び出される側は修正しないからね。

### ポリモーフィズムとは
呼び出される側が増えても、呼び出す側を修正しなくておk
それを達成する方法が、rubyのメソッドのオーバーライド

## 継承
OOPのクラスは、インスタンスを分類するより、**インスタンスの製造装置**

OOPの継承は、**クラス定義の共通部分を別クラスにまとめて、コードの重複を排除する仕組み**
親クラスと子クラスって言われるから紛らわしくなる原因もある。

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

## コンパイラ方式
文字通りコンパイルする。パフォーマンスは良いけど実行までに時間がかかる。企業の基幹システムでよく使われる。異なるプラットフォームだと動かない

## インタプリタ方式
rubyのこと。実行したら動く。実行までが早いけどパフォーマンスが遅い。異なるプラットフォームでも動く。

## 中間コード方式
Javaと.NETがこれ

## プロセスとスレッド
### プロセス
エクセルのアプリなど、**スレッドよりも大きな単位**
### スレッド
印刷機能など、機能のうちの1つ。複数存在できる

## メモリを管理する3つの領域
### 静的領域（メソッドエリア）
プログラム開始時から終了までずっといる

### ヒープ領域
たくさん領域持ってる。
インスタンス生成する時に、ヒープ領域に必要な大きさが割り当てられる

### スタック領域
スレッドに1つずつ用意される

## クラス情報はクラスに付き1つだけロードされる
### メモリを読み込む処理
1．事前にクラスのメソッドを全て読み込む
2．必要に応じてメソッドをロードする

OOPは**有限のメモリ領域のヒープ領域を大量に使って動くこと**を認識しろ！

インスタンスを格納する変数には、インスタンスそのものではなく、**ポインタ**が格納される！

## ポインタとは
メモリ領域の場所を示す情報

メソッドの引数や戻り値にオブジェクトを指定しても、**実際に受け渡すのはポインタ**

## ガベージコレクション
いらないメモリを集めるのは、ガベージコレクタっていうプログラムがやる。

すごい分かりやすく言うと、
ガベージコレクタ大魔王が、誰からも手を繋がれていない（ぼっち）インスタンスを見つけて、その場でぶっ殺すこと！

# 6章　OOPがもたらしたソフトウェアとアイデアの再利用

フレームワークは、全ての処理をFW側で決めておき、アプリケーションの処理はポリモーフィズムを使って必要な時に呼び出す
Tips：アプリからFWを呼び出さないように作ることを、ハリウッドの原則っていう

## アプリケーション固有の処理は、ポリモーフィズムを利用して呼び出す
Railsでいうと、モデルごとに処理が違うのはこれのおかげってこと？
フレームワークで用意されたメソッドを使うだけで、複雑な処理を書かずにアプリを作れる！

## デザインパターン
Javaのライブラリの中には、デザインパターンと全く同じ設計のものがある、
これがライブラリはデザインパターンを参考に作られた証拠

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

繰り返しだけど、オブジェクト指向は現実の代わりにはならない。
病院に置き換えたときでも、システム的な処理はできるけど、患者に向き合うのは人間じゃないと無理。
コンピューターは一部を肩代わりするだけ。得意なのは決まった処理。

##  集合論
従業員クラスを作って、インスタンスとして山田さん田中さんがいる。

## 役割分担
クラスごとに役割を分ける

上記2つを使うことで、オブジェクト指向で様々な表現ができる

上流工程は**汎用の整理術**
設計以下の下流工程は**プログラミング技術**

## クラス図
集合論で分類・整理した現実世界の物事の関係性を表す

## シーケンス図
役割分担された人や組織が強調して全体の仕事を達成する様子を時系列で表す

## コミュニケーション図
役割分担された人や組織が強調して全体の仕事を達成する様子を構造中心に表現する

## ユースケース図
システムの全体像をつかむためにめっちゃ使えそう。
各関係者（一般ユーザーや管理者など）のアクションが一括して見れる。システム作るときにも楽だし説明もしやすい！！

## アクティビティ図
現実世界の仕事の流れを表す

## ステートマシン図
外部からのイベントによる状態変化を表す

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

## 3ステップでギャップを埋める

### 1．業務分析
どういう役割分担でどうやって進めてるのか整理する。
課題を抽出して、なぜコンピューターを利用するのか？を整理

### 2．要件定義
コンピューターに何をさせるのかを決める

### 3．設計
コンピュータでどうやって実現させるか決める

## ビジネスアプリケーションでは、データ構造が現実世界を反映する

## 組み込みソフトウェア
携帯電話だったりカーナビーとか色々
特徴は**現実世界の仕事をそっくりそのまま置き換える**

# 10章　擬人化して役割分担させるオブジェクト指向設計
良い設計とは、**凝縮度が強く、結合度が弱い**

昔は実行効率が重要視されてたけど、
今の時代で大事なのは、**保守性や再利用性**

## 再利用しやすいソフトウェア構造

### 1．重複を排除する
設計の段階で、できるだけ機能の重複が起きないように

### 2．部品の独立性を高める
修正するには既存のシステムを理解しないといけない。
「分ければ、分かる」
**個々のサブシステムや部品の独立性を上げる**
変更する時に修正箇所が特定しやすくなる。
他への影響を最小限に抑えられる

## 凝縮度
個々の部品の機能のまとまり度合いが強い。

## 結合度
部品の結びつきが弱い。

## 大事なこと
個々の部品はギューッと、部品間のやりとりはアッサリと。
現代で例えると、よそ者は殺して身内の結束を高めて、近所付き合いはできる限りしない。

## 凝縮度を上げるコツ
### 1．クラス名やメソッドを一言でズバリと表せ！
### 2．秘密をたくさん作る。外部から参照させない。privateとか隠す仕組みを使え！
### 3．小さく作れ！

## 3．依存関係を循環させない
ソフトウェアの**秩序を持ち込むために**、クラスの依存関係を循環させない。
秩序がないと無法地帯になって超やばい！

コンポーネントAとコンポーネントBが結びついてると、Aを修正したらBが死ぬ。

## 設計のコツ？
感覚的な部分もあるけど、
一つのタスクを、複数のクラス（オブジェクト）で分割して行うことで、クラス間の独立性が高くなる！
そのおかげでアプリ全体の保守性や再利用性がアゲアゲになる

コツは、**汎用の整理術とプログラミング技術の両方を考えること**