More Related Content
Similar to モジュールの凝集度・結合度・インタフェース
Similar to モジュールの凝集度・結合度・インタフェース (20)
モジュールの凝集度・結合度・インタフェース
- 1. インタフェース
と
モジュールの
凝集度
と
結合度
柳川 一芽
twitter: yangiYA
WEB: http://ti.que.jp/p/
- 2. インタフェースって重要です
• 優れたインタフェース設計なら
– 改造は簡単です
– 機能追加は簡単です
– 公開インタフェースを変更せず、内部実装をリファクタリング
することでソースを改善できます。
(インタフェースのリファクタリングは影響範囲が広い)
– 使う人が簡単に使い方を理解できます
• � 驚き最小の原則
– 使う側が使いたい使い方ができます
- 12. �
• このマークと一緒に、
テーマと関係ある
『格言』『金言』『ちょっといい話』を
付記しました。
–実は、今回の勉強会の内容より、
頭にのこるのではと期待してます
- 14. その前に、モジュール って?
� よく、各人のモジュールの意味がズレ易いので、
あわせておきます
� 1ひとまとまりのプログラム
� ボヤっとしてますが、
今日のところはこれでお願いします。
- 15. 具体的なものにモジュールを
当てはめて見ると
� クラス1つ。
と考えるとだいたい、当り
� たまに、
メソッドとか関数の意味でも使います
- 17. モジュールの凝集度
• 機能的凝集
• 逐次的凝集
↑ 凝集度が高い
• 通信的凝集
強度が 強い
• 手順的凝集
---良い
• 時間的凝集
• 論理的凝集
↓ 凝集度が低い
強度が 弱い
• 暗号的凝集
---悪い
• どのぐらい純粋か 、の尺度
- 18. モジュールの凝集度
• 凝集度のいいイメージ
– ギュー っと機能が集まっている感じ
• 凝集度が高いと
– モジュールの独立性が高い、つまり、
– 修正しやすい
– ソースを理解しやすい
– � 単一責任原則(Single Responsibility Principle)
- 19. モジュールの凝集度
• 古いです
• 「モジュールの強度」
という呼び方をされる場合もある
– 1970年末から80年に出てきた概念
– 当時は「構造化設計」
っていうプログラム設計手法が主流
– オブジェクト指向言語は出てきたばかり
• 1972年 Smalltalk
• 1972年 C++
- 23. 論理的凝集
• 似た機能が集まっているが、
よく見ると異なる機能が1つのモジュールに含まれている。
• 機能種別(フラグなど)をパラメータで指定して、
実は複数の機能を提供しているような場合
• 寸評
– よく見かけるけど、if文がいっぱい。
(残念な感じがするプログラム。凝集度も低い)
– 機能種別が増えると収集がつかなくなる。
– 機能追加は正しく動いているソースを修正することになりやすい
• � オープン・クローズドの原則 (Open-Closed Principle)
– private メソッドで、種別が on・off だけなら効果的な場合もある
• � DRY - Don't Repeat Yourself.
- 24. 時間的凝集
• ある時にまとめて実行する処理をまとめている
– 「初期処理」 とか 「エラー処理」 とかをまとめたモジュール
のような感じ
• 別名
– 一時的凝集
• 寸評
– 凝集のレベルとしてはそんなに高くないけど
効果的な場合あり
• 同じような機能をいろんなところで作らないですむ。
• 近い箇所で実行するソースがまとまっていると、
ソースを理解しやすい
- 26. 通信的凝集
• 関係あるデータ使って、
いくつかの機能を実行するモジュール
• 機能の順序はあまり意味がない
• 後述の逐次的凝集と分類しない場合もある
• 別名
– 連絡的凝集
• 寸評
– 凝集度高め
– いいと思う
- 27. 逐次的凝集
• 関係あるデータ使って、かつ、
実行する機能の順番に意味がある。
(通信的凝集かつ手順的凝集のようなもの)
• 前述の通信的凝集と区別しない考え方もある
• 別名
– 連絡的凝集
• 寸評
– 凝集度はかなり高い
- 38. • 次は、
新しい機能を追加した場合の
モジュール改造 イメージ
• 凝集度が
高い場合と、低い場合とを
比べます
- 48. モジュールの結合度
• モジュールとモジュールが
どのくらい強く結びついているか
• 『疎結合』という言葉は
「モジュールの結合度」が低いということです
• 疎結合を関係が深いキーワード「Webサービス」
– 「Webサービスにしたから疎結合」ではなく、
「疎結合なインタフェースでWebサービスを提供する」
であるべきです
- 49. モジュールの結合度
データ結合
•
• スタンプ結合
↑ 結合度低い
良い
• 制御結合
• 外部結合
• 共通結合
• 内容結合 ↓ 結合度高い
悪い
• どのぐらい、独立しているかの尺度
- 52. 共有結合
• 共通領域(グローバル領域)に定義されたデータを参照する。
• 寸評
– 結合度が高い。保守開発の影響度が広くて、改修しにくい。致命的
– マルチスレッドで予測不能の振る舞いをするリスクあり。
(安全に使えない)
– Javaで見かけるパターン
• staticフィールド、シングルトンオブジェクトを不用意に使ったもの
• 大きなオブジェクトの参照を呼び出し先に渡しまくったり、
public でどこからでも参照できたりさせる
– 正しく設計したシングルトンパターンオブジェクトでは使います。
• 属性を持たないロジックだけのシングルトンは、
共有結合とは関係ない。
- 53. 外部結合
• 必要なデータだけを外部宣言し、ほかのモ
ジュールから参照を許可し共有する。
• 寸評
– 共有結合とほとんど同じ。改修しにくい。
• 利用する側が、使う項目を明確にして、
その項目以外使わなということが分類上違う模様
(でも、保守開発で影響度をきにしないといけなくなること
は、ほとんど変わらないと思う。)
- 54. 制御結合
• 機能コードなど、モジュールを制御する要素を引数
として相手モジュールに渡し、モジュールの機能や
実行を制御する。
• モジュール凝集度の論理的凝集度がこれに相当
する。
• 寸評
– 論理的凝集とおなじく、if文がいっぱいで、
よく見かけるけど残念なレベルです。
– 論理的凝集の繰り返しになりますが、
private メソッドで、種別が on・off だけなら効果的
- 55. スタンプ結合
• 相手モジュールで、
構造体データ(レコード)の一部を使用する場合でも、
構造体データすべてを引数として相手モジュールに渡す
• 寸評
– Daoで取得したテーブルのDTOをそのまま引数で渡すような
場合が該当する。必要な項目を限定すべきだが、面倒なので
ついやってしまう。(プログラムを作るうえで面倒だという感覚
は重要でトレードオフの対象になると思う)
– 引数を渡した先で書き換えられる危険を増やしていることに留
意する必要がある。(難解なバグになるかも)
• � 防御的コピー.
- 56. データ結合
• 相手モジュールをブラックボックスとして扱い、
必要なデータだけを引数として渡す。
• 寸評
– 結合度は最も低い。
全部これにできることが理想
– 値渡しなら、呼び出し側で引数が変えられる心配なし
– 参照(ポインタ)渡しの場合は、
引数を渡した先で書き換えられる危険性がある
- 60. A機能 B機能
インタフェースが
コンパクト
• パラメータと戻り値の項目数が少なくすれば、結合
度が低くなります(ざっくり言ってみました)
- 66. 思い出そう:オブジェクト指向
• 『データ』と『処理』を一まとまりにする
– データ
• 意味のあるデータの集まり
– 処理
• メッセージとかメソッドとかサービスとか呼ばれるもの
• メッセージの協調(連続)で、機能を実現
– オブジェクトからオブジェクトへ、
(短い)メッセージを送る行為が繰り返され、
全体の機能を実現する。
– メッセージを送る ≒ メソッドを呼び出す
- 67. 思い出そう:オブジェクト指向
• 『データ』と『処理』を一まとまりにする
– データ
機能的凝集
• 意味のあるデータの集まり
高い凝集度
– 処理
• メッセージとかメソッドとかサービスとか呼ばれるもの。
• メッセージの協調(連続)で、機能を実現
– オブジェクトからオブジェクトへ、
(短い)メッセージを送る行為が繰り返され、
スタンプ結合
全体の機能を実現する。 データ結合
– メッセージを送る ≒ メソッドを呼び出す 低い結合度
- 70. オブジェクト指向設計
とは言いにくいケース
• クラスにstaticメソッドしかない
– ユーティリティライブラリ
• フィールドとgetterとsetterしかない
– データトランスファーオブジェクト(DTO)
• メソッドはあるがフィールドが1つもない
– サーブレットクラス、
シングルトンのビジネスロジック、
ステートレスBean(EJB)
- 71. オブジェクト指向で全部作ら
なくてもいいけど・・
• オブジェクト指向、全然使ってないように感じます
• DTO、や、StrutsのFormにちょっと編集メソッドを加える
と、オブジェクト思考っぽくなります。
(すごく簡単。手始めとしてはオススメ)
– getPrice() ==> "10000"
– getPriceForView() ==> "10,000 -"
• こっちのほうが、タグを使うより簡単にコードの重複が減らせるます
– � DRY (Don't Repeat Yourself.)
- 74. どんなインタフェースが良いのか
• 結合度をを低くする
– 引数はすくない方がよい。引数なしが最も低い
• DTOを渡すのは引数をたくさん渡すのと同じ
• 機能を実現するための必要最小限の引数を
• 返却値は(できれば)凝集度を高く
– こちらはそんなにがんばらなくてもいいと思います
• インタフェースで使う人が機能を想像できる
– � 驚き最小の原則
• 「作りやすいから」ではなく「使いやすいから」で決める
– � TDD(Test Driven Development) - 作る前に使え
- 84. データが取得できない場合
何が起こるか
• 返却例
– NULL
– 空のリスト
– 例外
– Nullオブジェクトパターン のオブジェクト
• ポイント
– 『事後条件』を明らかにしてください
- 85. 取得想定されるレコードは何件かを意識
する
• まず、1件返却なのか複数件返却なのかを明確に
– 1件なら、Listや配列を返してはいけない
– 複数件なら返却件数を意識してください。
• 20件程度、 1000件程度、 とてつもなく多い
– 返却件数に限界があるのならドキュメントに明示してください
• システム的に限界は
• 運用的に限界は
• ポイント
– 『事前条件』『事後条件』を明らかにしてください
- 88. 引数は必須?任意?
• 任意なパラメータを避ける
– 「オーバーロード」とか「デフォルト引数」とかを使って
• 任意はパラメータを用意する場合は、
設定するか否かで何起こるか明記してください
• どれが必須で、どれが任意か明示してください
• ポイント
– 結合度を低くしてください。
• 任意なパラメータは実質的に制御結合(結合度が高い)になっている
可能性があります
– 複数任意なパラメータがあると、
組み合わせの数は爆発的に増えて説明困難になる
- 89. 例外の意味は
• スローする例外の意味を説明してください
– ドメイン上の意味がある異常
• 意味ある例外を作ってスロー
– 処理の継続ができない異常
• 汎用的のランタイム例外をスローするのがいいケースが多い
– バグ、環境障害、のケースはこれ
• 例外がない言語の場合、呼び出し元に異常を伝える方
法を明示する
• ポイント
– 『事後条件』を明らかにしてください
- 96. ケーススタディー:引数検討
• インタフェース1
– 引数
• キー1
• インタフェース2
– (インタフェースはコンパクトにと説明しましたが、
こちらをオススメします)
– 引数
• キー1
• WebサービスのURL
• インタフェース1を作りたい場合、
インタフェース2 を呼び出して作ればいい