<輪読会>オブジェクト指向でなぜつくるのか - 第9~12章 -
輪読会メンバー
- Izumi Haruya
- Sekine Yutaro
- Abe Kaisei
第9章 現実世界とソフトウェアのギャップを埋めるモデリング
- ステップ❶(業務分析) : 現実世界の仕事の作り方
- ステップ❷(要件定義) : コンピュータに任せる仕事の範囲を決める
- ステップ❸(設計) : ソフトウェアをどう作るかを決める
第10章 擬人化して役割分担されるオブジェクト指向設計
- 設計の目標
参考書籍
オブジェクト指向でなぜつくるのか 第3版 知っておきたいOOP、設計、アジャイル開発の基礎知識 | 平澤 章 |本 | 通販 - Amazon.co.jp
<輪読会>オブジェクト指向でなぜつくるのか - 第5−8章 -
輪読会メンバー
- Izumi Haruya
- Sekine Yutaro
- Abe Kaisei
第5章 メモリの仕組みの理解はプログラマのたしなみ
OOPを使って書いたプログラム
- メモリの使い方に特徴があるので、メモリの使い方の理解が最低限必要になってくる
プログラムのメモリ領域
- メソッドエリア(静的領域)
OOPで書いたプログラムは、有限のメモリ領域であるヒープ領域を大量に使う
静的領域は、従来のメモリ領域で管理する方法 メソッドエリアとは上記で説明した、ヒープ領域で管理する方法
- ヒープ領域
- スタック領域
ガレージコレクションとは
第6章 OOPがもたらしたソフトウェアとアイデアの再利用
-
- 標準ライブラリ
- 汎用ライブラリ(外部から組み込むライブラリ)
フレームワークは2つある
第8章 UMLは形のないソフトウェアを見る道具
-
システムの振る舞いや構造をオブジェクト指向で分析したり設計したりする際、図を用いることで視覚的に把握できるようになり、効果的に表現できます。しかし、その図の描き方が人によって違っては困るので、標準規格として作られた図の記法(モデリング言語)
引用:Cacooブログ編集部
UMLの使い方
参考書籍
オブジェクト指向でなぜつくるのか 第3版 知っておきたいOOP、設計、アジャイル開発の基礎知識 | 平澤 章 |本 | 通販 - Amazon.co.jp
<輪読会>オブジェクト指向でなぜつくるのか -第4章 OOPは無駄を省いて整理整頓するプログラミング技術-
輪読会メンバー
- Izumi Haruya
- Sekine Yutaro
- Abe Kaisei
第4章 OOPは無駄を省いて整理整頓するプログラミング技術
- ポイント
- OOPの基本的な仕組み
- 以前と比べどこが優れているのか
OOPが持つ構造化言語にはない3つの仕組み
- クラス、ポリモーフィズム、継承がある
- 重複した無駄なロジックを排除し、必要な機能を整理整頓する仕組み
- 3つの仕組みは、構造化言語で解決できなかった「グローバル変数」と「貧弱な再利用」という2つの問題を解決するためのものである
三代要素1ークラスに関わる3つの仕組み
- クラスは「まとめて、隠して、たくさん作る」仕組み
- サブルーチンと変数を「まとめる」
- 結びつきの強い複数のサブルーチンと複数のグローバル変数を1つのクラスにまとめることができる
- 部品の数が減る
- メソッド(サブルーチン)の名前づけが楽になる
- メソッド(サブルーチン)が探しやすくなる
- 結びつきの強い複数のサブルーチンと複数のグローバル変数を1つのクラスにまとめることができる
- クラスの内部だけで使う変数やサブルーチンを「隠す」
- private、publicでアクセスする範囲を指定できる
- private → クラスの外部からアクセス不可
- public → クラスの外部からもアクセス可
- private、publicでアクセスする範囲を指定できる
1つのクラスのインスタンスを「たくさん作る」
// 従来の呼び出し方法 クラス名 // インスタンスが使用できるようになってからの呼び出し方法 インスタンス名 = new クラス名 インスタンス名.メソッド
- サブルーチンと変数を「まとめる」
三代要素2ー呼び出し側を共通化するポリモーフィズム
- メソッドを呼び出す側を共通化すること
- インターフェースの継承のこと
三代要素3ークラス定義の重複を排除する継承
型にはめられるとプログラマは楽になる
- 型を宣言する目的
- コンパイラにメモリ領域の大きさを教えるため
- プログラムのエラーを防止するため
クラスを型として利用する
- OOPではクラスを型として扱える
- 型付けには静的と動的の2つがある
さらに進化したOOPの仕組み
- パッケージ
- クラスをさらにまとめたもの
- 関連する役割を持つクラスを集め、全体の見通しを良くできる
- 例外
- 戻り値とは違う形で、メソッドから特別なエラーを返す仕組み
- 無駄を省くこと、間違いを防止することの2つの効果
- コンパイルエラー(静的型付言語)や実行時エラー(動的型付言語)がある
- ガベージコレクション
- インスタンスを削除する処理をシステムが自動的に実行する仕組み
OOPを生かすも殺すも心がけ次第
品質が高く、保守に強く、再利用しやすいソフトウェア作成はOOPを使おう!
参考書籍
オブジェクト指向でなぜつくるのか 第3版 知っておきたいOOP、設計、アジャイル開発の基礎知識 | 平澤 章 |本 | 通販 - Amazon.co.jp
<輪読会>オブジェクト指向でなぜつくるのか - 第3章 OOPを理解する近道はプログラミング言語の歴史にあり -
輪読会メンバー
- Izumi Haruya
- Sekine Yutaro
- Abe Kaisei
第3章 OOPを理解する近道はプログラミング言語の歴史あり
OOPは必然性を持って登場した
1940年代~
黎明期には機械語でプログラムを書いていた
このときコンピュータは、2進数で書いた機械語しか解釈できなかった
以下は算術計算を実行する命令であり、これを見ても直感的にわからないので、一部の物凄く優秀なプログラマしか扱えなかった
// 16進数 A10010 01D0
1950年代~
プログラミング言語の最初の一歩はアセンブリ語
- 人が解釈しやすいような記述方法
// アセンブリ言語 MOV AX, Y MOV DX, Y
上記はコンパイルするアセンブラという別のプログラムを読み込ませて機械語を生成していた また、命令をほんの少し間違えるとプログラムが暴走する懸念があった
1950年代 ~ 1960年代
高級言語の発明でプログラムはより人間に近づいた
- 高級言語になるとかなり人間が読みやすくなった
// FORTRAN Z=X+Y
1970年代 ~
分かりやすさを重視する構造化プログラミング
- GOTO文を廃棄した
- 注目を集めた構造化プログラミング
- 基本三構造
構造化プログラミングにも課題があった(メモリ、CPU速度) 上記のような問題は、ハードウェアの改善とともに問題も改善していった
19XX年代(その後) ~
サブルーチンの独立性を高めて保守に強くする
・ グローバル変数をいかに減らすか
・ 上記が多いと影響範囲が大きいので、変更コストが莫大にかかった
・ ビルドして、エラーハンドリングしようとしてもビルドに1日以上かかって現実的でなかった
- 問題を避けるための2つの仕組み
- ローカル変数(サブルーチンの中だけで使用される変数)
- 引数の値を渡す
上記をうまく使用することでサブルーチンの独立性を高めることが可能になった!!
GOTOレスプログラミングを実現する構造化言語
- 構造化言語(GOTOレスプログラミング言語)が登場した
- ALGOL
- Pascal
- C
上記の中でC言語が1番注目された
- ビット演算やメモリ領域を効率的に使用するためのポインタなどの細かな機能があった
- 関数ライブラリで組み上げるようにした
- 上記のことが理由で既存の言語コンパイラを改良しなくてもよくなった
進化の方向は保守性と再利用性を重視に変化した
- 生産性向上
- 命令を簡単に表現するための進化
- 高級言語までの進化では、命令の「高級化」による表現力の向上
- 命令を簡単に表現するための進化
- 保守性向上
- プログラムをわかりやすくするための進化
- 構造化言語における進化では、基本三構造
- プログラムをわかりやすくするための進化
- 品質向上
- 制約をつけて複雑さを避ける為ための進化
- 構造化言語における進化では、GOTOレスプログラミング
- 制約をつけて複雑さを避ける為ための進化
- 再利用促進
- 重複ロジックを排除して、部品化と再利用を促進するための進化
- 高級言語までの進化では、サブルーチン
- 構造化言語における進化では、サブルーチンの独立性強化
- 重複ロジックを排除して、部品化と再利用を促進するための進化
ここまでのプログラミング言語の残された課題はグローバル変数問題と貧弱な再利用
- グローバル変数問題
- 現状のローカル変数の仕組みでは、サブルーチンを跨ぐ処理ができなかった(ローカル変数はサブルーチンの呼び出しが終わると消えてしまう一時的なものだった)
- 上記を解決するには、グローバル変数に頼るしかない現状だった
- 貧弱な再利用
- ライブラリが充実していなかった
- ライブラリにないものを実現しようとしたらサブルーチンで実現しなければならなかった
参考書籍
オブジェクト指向でなぜつくるのか 第3版 知っておきたいOOP、設計、アジャイル開発の基礎知識 | 平澤 章 |本 | 通販 - Amazon.co.jp
<輪読会>オブジェクト指向でなぜつくるのか -第2章 オブジェクト指向と現実世界は似て非となるもの-
輪読会メンバー
- Izumi Haruya
- Sekine Yutaro
- Abe Kaisei
第2章 オブジェクト指向と現実世界は似て非となるもの
オブジェクト指向を現実世界に対比して説明する
クラスは種類、インスタンスは具体的なモノ
クラス
- 同種のものの集まり
-
- 具体的なモノ、実例
メッセージパッシングとは、メソッドを呼び出すこと
ポリモーフィズムはメッセージの送り方を共通にする
継承は共通点と相違点を体系的に分類して整理する
- 継承の仕組み
- モノの種類の共通点と相違点を体系的に整理する仕組み
比喩を強調した説明は混乱を招きやすい
オブジェクト指向と現実世界は似て非なるもの
現実世界の違い
- 先に具体的なモノ(インスタンス)があり、それを見る側の立場や興味の違いによって、色々な基準で分類(クラス)する
プログラミングのための仕組みと割り切って理解する
- 三大要素を保守性や再利用性を上げる為の仕組みとして割り切る
- クラス
- 変数とサブルーチンをひとまとめにして独立性の高い部品を作る為の仕組み
サブルーチン(英: subroutine)は、コンピュータプログラミングにおいて、プログラム中で意味や内容がまとまっている作業をひとつの手続きとしたものである。 繰り返し利用されるルーチン作業をモジュールとしてまとめたもので、呼び出す側の「主」となるもの(メインルーチン)と対比して「サブルーチン」と呼ばれる。
- ポリモーフィズムと継承
- コードを重複を排除して汎用性の高い部品を作る為の仕組み
- クラス
そもそもソフトウェアは現実世界をそのまま表現しない
- システム化範囲の議論
- (一般論)ソフトウェアが人間の仕事をまるごと置き換えてしまう
- (本書の結論)ソフトウェアがカバーするのは人間の仕事の一部でしかない
上記の続きは第9章で詳しく議論予定(後ほど引用作成します)
現実世界と似ていることが可能性を広げた
- オブジェクト指向と現実世界は似て非なるものがもたらした可能性
- 上流工程
- 下流工程
これらが渾然一体となって「オブジェクト指向」というコンセプトの魅力を高め、IT業界のバズワードとしても使われるようになりました。
引用:オブジェクト指向でなぜつくるのか P49
参考書籍
オブジェクト指向でなぜつくるのか 第3版 知っておきたいOOP、設計、アジャイル開発の基礎知識 | 平澤 章 |本 | 通販 - Amazon.co.jp
<輪読会>オブジェクト指向でなぜつくるのか -第1章 オブジェクト指向はソフトウェア開発を楽にする技術-
輪読会メンバー
- Izumi Haruya
- Sekine Yutaro
- Abe Kaisei
まえがき
- 旧版と比べて第3版の変更点
- 「オブジェクト指向がなぜ難しいのか」をより客観的な視点で説明することに注力するようになった
引用:オブジェクト指向でなぜつくるのか P10
(本書で気になる問い)
- モデリングとコミュニケーションを重要視する
- 「一見凄そう」で終わらない(理解しようとする)姿勢が大事
第1章 オブジェクト指向はソフトウェア開発を楽にする技術
オブジェクト指向はソフトウェア開発の総合技術
- オブジェクト指向でなぜ作るのか
- ソフトウェアを楽に作るため
- 難しいソフトウェア開発を楽に行うための総合技術である
モノ中心にソフトウェアを組み上げる開発手法
- 手続き型(システム全体を集合的に扱っている)
- (デメリット)仕様変更や機能追加の際の修正範囲が広い
- (デメリット)ソフトウェアの再利用が難しい
- オブジェクト指向(システムを部品に分け、独立性を持たせ、システム全体を構築している)
- (メリット)仕様変更や機能追加の際の修正範囲が狭い
- (メリット)ソフトウェアの再利用が容易
プログラミング言語から総合技術に進化した
引用:オブジェクト指向でなぜつくるのか P23
オブジェクト指向が難しい理由
プログラミング言語の仕組みが複雑
- 今までは仕組みが単純だったが、技術発展と共に仕組みが複雑になっていった
- 単純にコードを上から読むでは済まなくなってしまった
- 上記の理由から使いこなすまでには時間がかかるようになった
- 用語自体が難しい
- 今までは仕組みが単純だったが、技術発展と共に仕組みが複雑になっていった
比喩を使った説明による混乱
- 説明時の比喩が独特なことが多く、情報の中身よりも比喩の印象が強く残ってしまう
オブジェクト指向というコンセプトが抽象的
- モノ中心というコンセプトが抽象的である
- 現実世界とコンピュータの世界は似て非なるものである
上記のことからそのまま当てもはめてもうまくいかない
(独自の解釈)業務委託などの場合では、手続き型とオブジェクト指向の中間など、明確なポジションを取ることが少ない場合があるため、実務との乖離が生じ、理解しにくいケースもある
オブジェクト指向技術のwhatとwhyを説明する
本書の目標
- 論理の飛躍をせずわかりやすく説明すること
オブジェクト指向を難しくしている理由3つに対する方針
- プログラミング言語の歴史を踏まえて、メリットを具体的に説明する
- 比喩による説明は最小限に抑えて説明をする(比喩を使う場合はその旨を明示する)
- プログラミングの仕組みと、「モノ中心」で汎用的に物事を捉える考え方は別物として、分けて説明する
本書の構成
引用:オブジェクト指向でなぜつくるのか P30
上記の図で示す通り
前半部:プログラミング技術
後半部:プログラミング技術の応用
参考書籍
オブジェクト指向でなぜつくるのか 第3版 知っておきたいOOP、設計、アジャイル開発の基礎知識 | 平澤 章 |本 | 通販 - Amazon.co.jp
<輪読会> オブジェクト指向実践ガイド -第9章費用対効果の高いテストを設計する-
輪読会メンバー
- Izumi Haruya
- Sekine Yutaro
第9章費用対効果の高いテストを設計する
- 変更可能なコードを書く為の3つのスキル
- オブジェクト指向設計の理解
- コードのリファクタリングスキル
リファクタリングとは、ソフトウェアの外部の振る舞いを保ったままで、内部の構造を改善していく作業を指します。MartinFowler『新装版リファクタリング─既存のコードを安全に改善する』(児玉公信・友野晶夫・平澤章・梅澤真史共訳、オーム社、2014)
Sandi Metz. オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方 (Japanese Edition) (Kindle の位置No.5252-5255). Kindle 版.
- テストを書く能力
9.1意図を持ったテスト
- 一般的なテストのメリット
- テストを持つことの根拠として、最も一般的に言われていることは、テストはバグを減らすとか、文書になるだとか、テストを「最初」に書くことでアプリケーションの設計がより良いものになる、といったことでしょう。
Sandi Metz. オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方 (Japanese Edition) (Kindle の位置No.5274-5276). Kindle 版.
テストをすることの真の目的は、設計の真の目的がまさにそうであるように、コストの削減である
テストがなかった場合にかかるバグの修正に必要な時間や文書を書く時間、アプリケーションを設計する時間などに比べて、テストの記述、メンテナンス、実行に多くの時間がかかるのであれば、テストを書く価値はありません。
Sandi Metz. オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方 (Japanese Edition) (Kindle の位置No.5277-5281). Kindle 版.
- テストにコストがかかることの解決方法
テストをやめることではありません。うまくなることです。テストから優れた価値を得るには、意図の明確さが求められます。そして、何を、いつ、どのようにテストするかも知らなければなりません。
Sandi Metz. オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方 (Japanese Edition) (Kindle の位置No.5288-5290). Kindle 版.
テストの意図を知る
- 本書におけるテストの真のメリット
- バグを見つける
- バグの初期段階での修正は、いつでもコストの削減になる
- 仕様書となる
- 人の記憶と異なり、忘却や改ざんに依存せず、唯一信用できる設計の仕様書となる
- 設計の決定を安全に遅らせる
- 抽象的な(インターフェースに依存する)テストを書くことで、設計の決定を安全に遅らせることができる
- 抽象を支える
- より良い設計に近づけていく為に、徐々に抽象度を上げる形でコードを修正していく
- テストをすることで、あらゆる抽象のインターフェースを記録する
- 設計の欠陥を明らかにする
- テストのセットアップに苦痛が伴うようであれば、コードはコンテキストを要求しすぎていることが分かる
- 1つのオブジェクトをテストするために、ほかのオブジェクトをいくつも引き込まなければならないのであれば、そのコードは依存関係を持ちすぎてる
- テストを書くのが大変なのであれば、ほかのオブジェクトから見ても再利用が難しい
- 上記なような課題が見えてきたら、疎結合なテストを書くべきである
- バグを見つける
何をテストするかを知る
一般規則として、オブジェクトは、自身のパブリックインターフェースを構成するメッセージに対して「のみ」テストをするべきである
パブリックインターフェイス以外をテストする必要がないからといって、それらのテストをまったくしなくてよいというわけではない
- テスト対象に関するまとめ
いつテストをするかを知る
テストの方法を知る
テストの方法
テストをするときのオブジェクトのカテゴリー
- 自身がテストをするオブジェクトであること
- そのほかのものすべて
9.2受信メッセージをテストする
- 受信メッセージ
- オブジェクトのパブリックインターフェースを構成し、原則テストを必要とする
- 依存されていない受信メッセージは削除する
パブリックインターフェースを証明する
受信メッセージのテストに求められること
- 考えられ得るすべての状況において正しい値を返すことを証明すること
オブジェクトが単一責任になっていないケースでのテストの懸念
- テストの実行時間がかかる
- 想定外の結果が起こる可能性が高まる
9.3プライベートメソッドをテストする
パブリックインターフェイス以外は、送られたことがテストされるべきである
テスト中ではプライベートメソッドを無視する
- プライベートメソッドのテストをしないことを支持する理由
- パブリックでもテストされる事が多く、冗長になる為
- プライベートメソッドは、依存関係がある場合が多いので不安定である
- 依存関係があるので、テスト対象オブジェクト以外も記述する必要が出る可能性があり、テストの文脈が伝わらない
プライベートメソッドのテストをするという選択
- 設計の決定を遅らせることが目的の場合
9.7まとめ
- テストを書くのが難しい時は設計に問題がある
- 上記は依存関係が複雑であり、疎結合でない為難しくしてしまっている
- 設計全体が疎結合で単一責任になっている(パブリックインターフェイスの)時は、いかなる状況でも期待する値が返ってくるか検証するテストを書く
- 依存関係が複雑(プライベートメソッド)の場合は、基本的にはテストをしない
- 上記でも例外があり、設計の決定を遅せるのが目的の場合は、テストを記述する方が良い時もある。ただし、そのテストは「振る舞い」をテストすべきである
- テストの内容が具象すぎる時は、ダックタイピングやモジュール・継承の考えを用いてテストそのものを疎結合なものとする
参考書籍
オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方 | Sandi Metz, 髙山泰基 | 工学 | Kindleストア | Amazon