読んだ本
「プリンシプル オブ プログラミング3年目までに身につけたい一生役立つ101の原理原則」
この記事では、3章の アーキテクチャ根底技法 について記載します。
アーキテクチャ根底技法
Enabling Techniques for Architecture
どういうこと?
良いソフトウェア・アーキテクチャ構築のための基礎原理。
以下の技法がある。
- 抽象
- カプセル化
- 情報隠蔽
- パッケージ化
- 関心の分離
- 充足性、完全性、プリミティブ性
- ポリシーと実装の分離
- インタフェースと実装の分離
- 参照の一点性
- 分割統治
技法1: 抽象
Abstraction
どういうこと?
抽象とは、概念的に明確な「線引き」を行うこと。
抽象は、2つの観点がある。
- 抽象
- 一般化
例)楽器(ピアノ・バイオリン・チェロ)の場合、
- 抽象化:複雑な対象のいくつかの性質を捨て去り、特定の性質に目を向けること
- 一般化:具体的な対象から共通の性質を抽出し、より汎用的な概念に定式化すること
//抽象化
楽器(具体的な個体の集合・製造番号) → 楽器の種類(商品番号)
//一般化
ピアノ・バイオリン・チェロ → 楽器
参考: 5分30秒〜
https://www.youtube.com/watch?v=X9HbfKswJHc
技法2: カプセル化
Encapsulation
関連のあるデータとロジックをグルーピングして、1つのモジュールにまとめる。
カプセル化には以下のメリットがある。
- 関連のない要素が混じらないため、コードが見やすくなる
- 変更時の影響が、モジュールないに閉じることになる
- 影響度が明確になるので、コードの変更が容易になる
- それぞれが独立した部品になるので、再利用性が高まる
- 小さい単位に分割されるので、複雑な問題に対処できる
技法3: 情報隠蔽
Infomation Hiding
モジュールにどのようなデータがあり、関数がどのようなロジックで機能を実現するかを外部から隠蔽する。
モジュールの持つデータは、外部から直接アクセスできないようにする。
クライアントから見ても余計な情報が見えないため、モジュールの使い方がシンプルになり、使い勝手が良くなる
カプセル化と情報隠蔽の違い
カプセル化
関係のある要素を集めてモジュール化すること。
関連の深いデータと関数を一箇所にまとめる。
情報隠蔽
モジュールの内部状態や内部関数を隠蔽すること。
内部に対する外部からの直接アクセスを遮断する。
技法4: パッケージ化
Packaging
モジュールを意味のある単位にまとめ、それをグループ化する。
これはソフトウェア全体を意味のある単位に分割すること。これをパッケージと呼ぶ。
利点
- ソフトウェア全体が、パッケージという小さい単位に分割されるので、複雑度が下がる
- パッケージ内は関係のないモジュールが混じらないので、モジュールの管理がしやすくなる
- 修正に対して、影響度がパッケージ内に止まる可能性が高いので、コードが変更しやすくなる
- 依存関係が整理されることになり、パッケージを単位とした再利用をしやすくなる
パッケージの設計は、モジュールがある程度できてから、ボトムアップで設計する。
技法5: 関心の分離
Separation of Concerns
関心とは、ソフトウェアの機能や目的のこと。
関心ごとに。モジュールを作成し、互いに異なる責務や、無関係な責務は分離しておく。
最も代表的な設計技法のパターンはMVC(「ビジネスロジック・ユーザへの表示・入力処理」に分離している)
メリット
コードが関心ごとに分離されていれば、以下のメリットがある
- 関心ごとに独立して修正できるので、読む範囲が限られ、変更が容易になる
- 影響範囲が関心内に留まることになるので、変更時の品質が安定する
- コードを書くときは、関心を単位として開発するため、分業して並行して開発を進めることができる
技法6: 充足性、完全性、プリミティブ性
Sufficiency, Completeness, Primitiveness
モジュールの担っている抽象の表現は、「充足」し「完全」で「プリミティブ」であるべき。
充足性
モジュールが表現しようとしている抽象が、それを伝えるために十分であるか、ということ
例)モジュールがコレクションを表現しいているとき、remove
が提供されていてもadd
が提供されていなければ、コレクションであることを伝えるのは不十分
完全性
モジュールが表現しようとしている抽象が、全ての特徴を備えているか、ということ
例)モジュールがコレクションを表現しているとき、その要素数を取得するsize
が提供されていなければ、完全とは言えない
プリミティブ性
モジュールが表現しようとしている抽象が、全て純粋であるかどうか、ということ
例)モジュールがコレクションを表現しているとき、アイテムを1つ追加するadd
が提供されていれば、アイテムを10個追加するadd10
は必要ない
技法7: ポリシーと実装の分離
Separation of Policy and Implementaion
モジュールは、「ポリシー」あるいは「実装」を扱うが、1つのモジュールでその両方を扱ってはいけない。
「ポリシー」と「実装」が混ざっていると、ポリシーの変更に実装が引きづられ、再利用できなくなってしまう。
ポリシーモジュール
ソフトウェアの前提に依存する、ビジネスロジックや、その他のモジュールに対する引数の選択を行う部分
実装モジュール
そのソフトウェアの前提に依存しない、独立したロジック部分。
そのソフトウェアの前提条件については、モジュールに対する引数として与えられる。
技法8: インタフェースと実装の分離
Separation of Interface and Implementaion
モジュールは「インターフェース」パートと「実装」パートの2つの分離した部分から構成する。
使用者はインタフェースだけ知れば良い。
インタフェースを用いて設計する
技法9: 参照の一点性
Single Point of Reference
モジュールの要素で、宣言され定義されるのは1回切りにする。
そのために、単一代入を行う。
単一代入: 変数に対して、値の再代入を行わないこと
技法10: 分割統治
Divide and Conquer
そのままでは解決することが難しい大きな問題は、いくつかの小さな問題に分割して、個別に解決する