オブジェクト指向でなぜつくるのか -知っておきたいOPP、設計、アジャイル開発の基礎知識-

# はじめに
オブジェクト指向ってなんぞ？
そもそも機械語とかアセンブリ言語とか高級言語とか。。。知らん！ってことなので理解するためにまとめました。

# 第１章 オブジェクト指向はソフトウェア開発を楽にする技術
- オブジェクト指向は難しいソフトウェア開発を楽に行うための総合技術」
- オブジェクト指向はソフトウェアの保守や再利用をしやすくすることを重視する技術。個々の部品により強く着目し、部品の独立性を高め、それらを組み上げてシステム全体の機能を実現することを基本にする
- クラスライブラリやフレームワークは大規模なソフトウェアの再利用部品群を作る
- 再利用部分を作る際に利用されたお決まりの設計のアイデアがデザインパターン
- OOPの仕組みを利用して作るソフトウェア構造を図式表現する方法がUML(統一モデリング言語）

# 第2章 オブジェクト指向と現実世界は似て非なるもの
- オブジェクト指向プログラミングの三大要素と呼ばれる「クラス」、「ポリモーフィズム」、「継承」
- クラスは種類
- インスタンスは具体的なもの
- ポリモーフィズムは色々な形に変わる、多態性
- 継承は似たもの同士のクラスの共通点と相違点を整理する仕組み、全体集合をスーパークラス、部分集合をサブクラスと呼ぶ
- 現実世界とオブジェクト指向は似て非なるものである

# 第3章 OOPを理解する近道はプログラミング言語の歴史にあり
- コンピュータは２進数で書いた機械語しか解釈できない
- 機械語の非効率なプログラミングを改善するためにアセンブリ言語、無機質な機械語を人間がわかりやすい記号に置き換える
- コンピュータが理解する命令を一つ一つ記述するのではなく、より人間にわかりやすい「高級な」形式で表現するのが高級言語
- プログラミングのロジックは順次進行、条件分岐、繰り返しの３つの構造である構造化プログラミング。この３つを合わせて基本三構造と呼ぶ
- プログラムの複数の場所に現れる同じ命令の並びを一箇所にまとめ、プログラムサイズを小さくしプログラム作成の手間を減らすことをサブルーチンと呼ぶ
- 複数のサブルーチンが共有する変数のことをグローバル変数
- ローカル変数はサブルーチンの中だけで使われる変数、サブルーチンに入った時に作られて、サブルーチンから抜ける時には消える
- 引数の値渡しは、サブルーチンに引数として情報を渡す際に、呼び出し側が参照している変数を直接使わずに値をコピーして渡す仕組み。サブルーチンの処理結果も戻り値として値渡しでやり取りすること
- プログラミングに必要な機能を関数ライブラリで組み上げることで、言語コンパイラを改良しなくても言語仕様レベルの機能追加ができる
- 

# 第4章 OOPは無駄を省いて整理整頓するプログラミング技術
- OOPの三大要素、「クラス」、「ポリモーフィズム」、「継承」
- OOPにはグローバル変数を使わずに済ませる仕組みが備わっている
- OOPには共通サブルーチン以外の再利用を可能にする仕組みが備わっている
- クラスは「まとめて、隠して、たくさん作る」仕組み
1.サブルーチンと変数を「まとめる」
2.クラスの内部だけで使う変数やサブルーチンを「隠す」
3.１つのクラスからインスタンスを「たくさん作る」
- OOPではクラスにまとめたサブルーチンをメソッドと呼び、グローバル変数をインスタンス変数と呼ぶ
- 結びつきの強いサブルーチンとグローバル変数を１つに「まとめる」ことができる、メリットは部品の数が減り、メソッドの名前づけが楽になる、メソッドが探しやすくなる
- クラスに定義した変数とメソッドを他のクラスから「隠す」ことができる、これによりプログラムの保守性悪化の元凶となるグローバル変数を使わずにプログラムを書くことができる
- 一旦クラスとして定義すると、実行時にそこからいくつでもインスタンスを作ることができる、これにより、ファイル、文字列、顧客情報など同種の情報を複数同時に扱う処理であっても、クラス内部にロジックを移せる
- インスタンス変数は、長持ちするローカル変数または仲間内だけのグローバル変数
- ポリモーフィズムは共通メインルーチンを作る仕組み、サブルーチン（メソッド）を呼び出す側のロジックを一本化する仕組み
- 継承は「クラスの共通部分を別クラスにまとめる仕組み」
- OOPでは、共通クラスのことをスーパークラス、それを利用するクラスをサブクラスと呼ぶ
- 変数に型を指定する理由は、コンパイラにメモリ領域の大きさを教えるためとプログラムのエラーを防止するため
- OOPではクラスを型として扱うことができる
- 型チェックの仕組みはプログラミング言語の種類によって異なり、性的な型付け方式はプログラムのコンパイル時点でエラーを検出し、動的な型付け方式はプログラムの実行時点でエラーを検出する
- クラスをさらにまとめるのが「パッケージ」でメソッドやインスタンス変数を定義はできない
- 例外は「戻り値とは違う方式で、メソッドから特別なエラーを返す仕組み」
- インスタンスを削除する処理をシステムが自動的に実行する仕組みをガベージコレクションと呼ぶ

# 第5章 メモリの仕組みの理解はプログラマのたしなみ
- プログラムの基本的な実行方法は２つ、コンパイラ方式とインタプリタ方式
- コンパイラ方式はプログラムに書かれた命令をコンピュータが理解できる機械語に変換して実行する
- インタプリタ方式はソースコードに書かれたプログラムの命令をその場で逐次解釈しながら実行する
- コンパイラ方式のメリットは実行効率が良い、コンピュータが機械語を直接読んでいるため
- コンパイラ方式のデメリットは実行するのに手間がかかり、コンパイラでエラーが見つかった場合、エラーがなくなるまで修正
- インタプリタ方式のメリットは手軽に実行でき、異なるプラットフォーム（マシンやOS）でも互換性を保てる
- インタプリタ方式のデメリットは実行速度の遅さ
- 高い処理能力が必要な場合はコンパイラ方式を採用するのが一般的。政府や銀行のシステム、企業の基盤システムなど
- インターネットを経由してさまざまな種類のマシンにダウンロードして動かすソフトウエアではインタプリタ方式を採用する。スクリプト言語などが典型的
- Javaなどは中間コード方式で、両方のいいとこ取りをしようとしている。同じプログラムを異なる実行環境で効率よく動かす
- 中間コードを解釈して動作する仕組みが必要なので、仮想マシンが必要
- スレッドを複数同時に実行できる環境をマルチスレッド環境、基本的にはOSの機能、無駄な待ち時間を減らして全体の処理効率を高めるため
- プログラムのメモリ領域は、静的領域、ヒープ領域、スタック領域の３つに分けて管理する
- 静的領域にはグローバル変数とプログラムの命令を実行可能な形式に変換したコード情報が格納されている
- ヒープ領域はプログラムの実行中にアプリケーションから必要なサイズを要求することで割り当てを行い、不要になれば元に戻す
- スタック領域はサブルーチンの引数やローカル変数、戻り先などの情報を格納している
- メソッドに書かれたコード情報は１クラスに１つだけロードする
- OOPで書いたプログラムは、有限のメモリ領域であるヒープ領域を大量に使って動く
- インスタンスを格納する変数にはインスタンスそのものではなく、インスタンスの「ポインタ」が格納される
- インスタンスを格納する変数を他の変数に代入した場合、ポインタがコピーされるだけで、ヒープ領域にあるインスタンスそのものは変化しない
- スーパークラスから継承したメソッドとインスタンス変数のメモリ配置は全く異なる
- スーパークラスのインスタンス変数は、ヒープ領域にあるサブクラスのすべてのインスタンスにコピーして保持する
- ガベージコレクタは、スタック領域とメソッドエリア（静的領域）から辿れなくなった不要なインスタンスを削除する

# 第6章 OOPがもたらしたソフトウェアとアイデアの再利用
- クラスライブラリでは以下のことが可能
1.ライブラリ中のクラスからインスタンスを作成して、メソッドと変数定義をまとめて利用する（クラスの利用）
2.ライブラリから呼び出される側のロジックをアプリケーション固有の処理で置き換える（ポリモーフィズムの利用）
3.ライブラリ中のクラスに、メソッドや変数を追加定義して新しいクラスを作成する（継承の利用）
- クラスライブラリとフレームワークは同義語として使われることも多い
- コンポーネントは、OOPのクラスよりも粒度が大きい、ソースコード形式ではなく、バイナリ形式として提供される、コンポーネントの定義情報を含めて提供される、昨日の独立性が高く、内部の詳細を知らなくても利用できる
- デザインパターンは設計のパターン
- GoFのデザインパターン

# 第7章 汎用の整理術に化けたオブジェクト指向
- コンピュータは現実世界の仕事の一部を肩代わりするだけである。したがって、コンピュータを司るソフトウエアも、現実世界をそのまま表現するわけではなく、一部の仕事を表現するだけ
- オブジェクト指向には、抽象的な「汎用の整理術」と、具体的な「プログラミング技術」という２つの側面がある

# 第8章 UMLは形のないソフトウェアを見る道具
- UMLとはソフトウエアの機能や内部構造を２次元の図に表現する形式を定めた世界標準、形のないソフトウエアを見る道具
- クラスや継承といったオブジェクト指向特有の仕組みを表現する図に加えて、従来から使われてきたフローチャートや状態遷移図なども取り込んだため、ソフトウェア開発における図式表現の集大成
- UMLの使い方は
1.OOPのプログラムの構造や動作を表現する
2.汎用の整理術としての成果物を表現する
3.オブジェクト指向で表現できない情報を表現する
- クラス図は、クラスを基本的な単位とするOOPのプログラム構造を表現する
- シーケンス図は、実行時のインスタンス間のメソッド呼び出しを時系列に表現する
- コミュニケーション図は、実行時のインスタンス間のメソッド呼び出しをインスタンスの関係を中心に表現する

# 第9章 現実世界とソフトウェアのギャップを埋めるモデリング
- コンピュータは「決まりきった仕事」と「覚える仕事」が得意
- ソフトウエアを開発する際に必要なステップ
1.現実世界の仕事の進め方を整理する(業務分析）
2.コンピュータに任せる仕事の範囲を決める（要件定義）
3.ソフトウエアをどう作るかを決める（設計）
- オブジェクト指向は上記３ステップを円滑に進めるためのモデリング
- モデリングの目的
業務分析：現実世界の様子をそのまま捉える
要件定義：コンピュータの性質を考慮して、肩代わりさせる仕事の範囲を決める
設計：ハードウエアの能力、OSやミドルウエアの特性、プログラミング言語の表現能力などを考慮して、ソフトウエアの構造を決める
- アプリケーションのモデリング内容の分類
1.ビジネスアプリケーション(企業などのビジネス活動を支援する）
2.組み込みソフトウエア（現実世界の仕事を置き換える）
3.スタンドアロンアプリケーション
上記を縁の下から支える基本ソフトウエア

# 第１0章 擬人化して役割分担させるオブジェクト指向設計
- 保守に強く、再利用しやすいソフトウエア構造の目標
1.重複を排除する（サブルーチン、ポリモーフィズム、継承など）
2.部品の独立性を高める（一言で表現する名前、秘密をたくさん作る、小さく作る）
3.依存関係を循環させない（「秩序を持ち込む」ため、パッケージやクラスの依存関係を循環させない）

# 第１1章 オブジェクト指向から生まれるアジャイル開発
- 開発プロセスは、ソフトウエア開発を円滑に進めることを目的として、作業項目や手順、成果物の形式、参加するメンバーの役割などを体系的に定義したもの
- ウォーターフォール型開発プロセス（要件定義、設計、プログラミング、テストの順番）
- 全体の計画をあらかじめ立てた上で、各作業を期限までに実施し、作成された成果物をレビューして承認するプロセスを経て次の段階に進む
- ソフトウエアの変更には大きなコストがかかる
- XP(エクストリームプログラミング）
1.コミュニケーション（チームメンバーや顧客とのコミュニケーションを重視する）
2.シンプルさ（計画に凝らずに、必要最小限のシンプルさを保つことを重視）
3.フィードバック（作ったプログラムはすぐに動かすテストを行い、その結果をフィードバックして改善する）
4.勇気（必要な場合には、勇気を持って設計を変更する）
- チームによる仕事の進め方の枠組みを定めたスクラム
- スクラムの大きな特徴の一つは、チームに参加するメンバーの役割を３つだけと定めている
1.プロダクトオーナー（作成するプロダクトの最終的な責任者。顧客の立場でプロダクトバックログの優先順位を決める権限を持つが、開発チームの作業に干渉してはならない
2.開発チーム（自己組織化されたチームのメンバーが機能横断的な作業に進めることを基本とする。ここのメンバーにはリーダーやアーキテクト、プログラマといった特定の役割を定義しない
3.スクラムマスター（スクラム手法を用いてチームの作業が円滑に進めるように支援するコーチ役）
- 優れたソフトウエアを手早く作るためのアジャイル宣言
- テストコードを先に書いて動かしながら開発する(TDD)
- テスト駆動開発（TDD）はテストコードを書く、コンパイルを通す、テストを実行して失敗することを確認する、コードを記述してテストを成功させる、コードの重複を取り除く
- リファクタリングは一旦完成したプログラムの外部仕様を変えずに、内部構造を安全に改善することを指す
- 継続的インテグレーション（CI)は、コードを常に出荷できる状態に保ちながら品質を維持する仕組み
- CIサーバーと呼ぶ専用マシン環境を用意し、コンパイル、ビルドから単体テストまでの一連の作業を、ツールを使って数時間おきに自動実行させる。ビルドやテストを定常的に行うことで、開発チームの誰かが欠陥を作り込んでしまった場合でも、すぐに問題を特定して対処できるようにする
- アジャイル宣言の理念を具体的に実践する手法の３つ
1.テスト駆動開発（TDD)：テストコードを先に書いてから本体コードを開発する
2.リファクタリング：完成したプログラムの内部構造を後から安全に改善する
3.継続的インテグレーション（CI)：コンパイル、ビルド、単体テストを定常的に自動実行する
- 上記のような反復型開発プロセスやプラクティスとオブジェクト指向の相性がいい
- TDDで利用する、xUnitと呼ばれる単体テスト用フレームワークはOOPの仕組みを活用して作られている

# 第１2章 オブジェクト指向を使いこなそう
- オブジェクト指向の次に来る技術、アスペクト指向、エージェント指向、サービス指向
- アスペクト指向は、OOPを使ってもプログラムのさまざまな箇所に分散してしまう共通な処理を分離して記述することで、柔軟性をより高める
- エージェント指向は、外部からのメッセージ受信によって初めて仕事をする受動的なオブジェクトの限界を打ち破るため、ユーザーの代理として、能動的に活動する「エージェント」を中心にソフトウエアを作り上げる考え方
- サービス指向は、複雑で巨大化したシステムを独立性の高いサブシステムの分散疎結合構成にする

# 終わりに
今までなんとなくで使っていたものがどのようなものか、機械語、アセンブリ、構化造言語からより良くなっていきOOP以外のことについても深く理解できてよかった

# 参考
オブジェクト指向でなぜつくるのか -知っておきたいOPP、設計、アジャイル開発の基礎知識-