「オブジェクト指向のこころ」を読んだのでざっくりまとめてみた
Contents
この本をざっくりと一言で表すと
適切な責務で分解をしてオブジェクトとして設計していくことで、
拡張に柔軟なアプリケーションを作ることが出来る
オブジェクト指向の原則
オブジェクトは適切な責務を伴い、自らに対する責務を有している
カプセル化は様々なものの隠蔽である
- データの隠蔽
- 実装の隠蔽
- ex. クライアントオブジェクトから隠蔽する、Bridgeパターン
- クラスの隠蔽
- 抽象クラス・インターフェース
- 設計の隠蔽
- 実体化の隠蔽
抽象をもとに設計をする
- 振る舞いやデータの流動的要素は共通性/可変性分析によって抽象化する
- インターフェースを用いて設計する
- 継承は「流動的要素を概念化する手段」として使う
- 既存オブジェクトを特殊化するためではない
- 結合度を高め、凝集度を低くするようにすること
- オブジェクトを使用するコードと生成するコードを分離する
コードは保守性を高くする
- OAOO(一度だけ)ルールを厳守する
- Once and Only Once
- 「意図によるプログラミング」
- 意図を明確に表すネーミングルール
- cf. リーダブルコード?
- コードのテスト可能性を考慮する
デザインパターン
パターンとは
何度も繰り返される問題を描写して、
問題を解決する上での核心を描写して、
その解決策を繰り返し適用できるようにしたもの
パターンによって特定のコンテキストにおける特定の問題についての
フォース(因果関係)、動機、関連を描写することができ、取り組むためのアプローチが示される
パターンを見るときの観点
- 何をカプセル化するのか?
- どのように共通性/可変性分析を用いるのか?
- どのようにして問題領域を責務に分解するのか?
- どのようにしてオブジェクト間の関連を規定するのか?
- どのようにしてコンテキストに基づく設計を浮き彫りにするのか?
デザインパターンを利用することの利点
パターンを用いて実装をカプセル化することでクライアントオブジェクトは
実装の詳細について知る必要がなくなる
→ 変更されやすい実装の決定をその時まで遅らせることができる!
※重要なのは責務を分解してわかったコンテキストに応じたパターンを分析して考える事
共通性/可変性分析とデザインパターン
概念上の観点(共通性)と実装上の観点(特定の流動的要素)を洗い出す
要は共通するオブジェクトを使うオブジェクトを考慮する、
ということが問題領域を責務の分解という異なった観点から捉えられる
「どういったオブジェクトが必要か」と
「こうしたオブジェクトの実体化の方法と管理方法」を別々で考えるべき、ということ
この「責務」を実装すべきオブジェクトを定義をしてから実体化の方法を考えるべきである
そのために「共通性/可変性分析」が有効
分析の方法(ざっくり)
ex. 下記の特殊ケースに関して分析を適用する
下記の要件を元に「形状描画プログラム」を作る
- 描画プログラム1を用いて正方形を描画したい
- 描画プログラム2を用いて円を描画したい
- 描画プログラム1を用いて長方形を描画したい
① 上のケースから以下の2つの共通性を見つけだす
- 描画プログラム(実装の詳細)
- 描画する形状(実装の抽象)
② すると以下の可変性を見いだせる
- 描画プログラム
- 描画プログラム1
- 描画プログラム2
- 描画する形状
- 正方形
- 円
- 長方形
- このうちの共通性が抽象となり、それらの関係性を定義することでインターフェースを考える
- そのインターフェースを元に可変性を表現する実装を考える
コンテキストに基づく設計をすること
上記の分析を用いて得られた抽象を元に基づいた設計をするということである
この抽象をコンテキストというが、つまり「クライアント側から見た仕様」のことであり、
常に利用側から見た抽象に基づいた設計をするべきということである
ざっくり言うと「依存性逆転の原則」を守ること、となる
例えば、インターフェースとポリモーフィズムを用いた設計などが言える
こうすることで、自然発生的にデザインパターンが導かれることもある
デザインパターンとは当てはめるものではなく、
こうしたコンテキストに基づいた設計のプロセスで導かれるものである
感想
自分に欠けていた視点を得ることができたと思います
特に抽象から実装に進んでいくというやり方を、これまで考えてきませんでした
今までの自分の書き方を思い返して、すぐに実装から考えてしまっていたなぁと反省ばかりです
手戻りや仕様変更で発生する悪夢が発生しうる危険なやり方であったため、考えを改めようと思います