Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

モジュールの凝集度・結合度・インタフェース

13.811 Aufrufe

Veröffentlicht am

社内勉強会発表用

内容
・モジュールの凝集度
・モジュール結合度
・オブジェクト指向
・インタフェース

  • Login to see the comments

モジュールの凝集度・結合度・インタフェース

  1. 1. インタフェース とモジュールの 凝集度 と 結合度 柳川 一芽 twitter: yangiYA WEB: http://ti.que.jp/p/
  2. 2. インタフェースって重要です• 優れたインタフェース設計なら – 改造は簡単です – 機能追加は簡単です – 公開インタフェースを変更せず、内部実装をリファクタリング することでソースを改善できます。 (インタフェースのリファクタリングは影響範囲が広い) – 使う人が簡単に使い方を理解できます • � 驚き最小の原則 – 使う側が使いたい使い方ができます
  3. 3. どうやれば優れたインタフェースに できる?•もっとも重要なコツは、
  4. 4. どうやれば優れたインタフェースに できる?•もっとも重要なコツは、状況に合わせてよく考えること
  5. 5. どうやれば優れたインタフェースに できる?•もっとも重要なコツは、状況に合わせてよく考えることだとは思いますが、
  6. 6. どうやれば優れたインタフェースに できる?• それ以外にあえて、•もう少し分かりやすい コツをご提案させて いただきます。
  7. 7. 良いインタフェースにするためのコツ• 今からあげるポイントに気をつけてJavadoc(かそれに近いドキュメント)を書いてください。そうすると、凝集度が高くなり結合度が低くなります
  8. 8. •本日言いたいこと (結論)です
  9. 9. Javadocを書いてください• クラスを説明する• データが取得できない場合何が起こるか• 取得想定されるレコードは何件かを意識する• 想定外の件数を取得したら?• ソートするの?• 引数は必須?任意?• 例外とその意味は• 引数が本当に必要か
  10. 10. 本日の結論 以上です
  11. 11. ご紹介する話題 (結論の背景として)• モジュールの凝集度 – 凝集度を高くする• モジュールの結合度 – 結合度を低くする• おまけ – オブジェクト指向 • オブジェクト指向を見直す – 契約プログラミング(契約による設計)• インタフェース
  12. 12. �• このマークと一緒に、 テーマと関係ある 『格言』『金言』『ちょっといい話』を 付記しました。 –実は、今回の勉強会の内容より、 頭にのこるのではと期待してます
  13. 13. その前に、モジュール って?� よく、各人のモジュールの意味がズレ易いので、 あわせておきます
  14. 14. その前に、モジュール って?� よく、各人のモジュールの意味がズレ易いので、 あわせておきます� 1ひとまとまりのプログラム� ボヤっとしてますが、 今日のところはこれでお願いします。
  15. 15. 具体的なものにモジュールを 当てはめて見ると� クラス1つ。 と考えるとだいたい、当り� たまに、 メソッドとか関数の意味でも使います
  16. 16. モジュールの凝集度
  17. 17. モジュールの凝集度• 機能的凝集• 逐次的凝集 ↑ 凝集度が高い• 通信的凝集 強度が 強い  • 手順的凝集   ---良い• 時間的凝集• 論理的凝集 ↓ 凝集度が低い 強度が 弱い  • 暗号的凝集   ---悪い• どのぐらい純粋か 、の尺度
  18. 18. モジュールの凝集度• 凝集度のいいイメージ – ギュー っと機能が集まっている感じ• 凝集度が高いと – モジュールの独立性が高い、つまり、 – 修正しやすい – ソースを理解しやすい – � 単一責任原則(Single Responsibility Principle)
  19. 19. モジュールの凝集度• 古いです• 「モジュールの強度」 という呼び方をされる場合もある – 1970年末から80年に出てきた概念 – 当時は「構造化設計」 っていうプログラム設計手法が主流 – オブジェクト指向言語は出てきたばかり • 1972年 Smalltalk • 1972年 C++
  20. 20. •凝集度の説明
  21. 21. •凝集度の説明• 退屈で分かりにくいですが一応一通りやります お付き合いください
  22. 22. 暗号的凝集• 関係のない機能をまとめてしまっている• なぜ、そこにそのメソッドがあるのが理由がみつからない• よく使うものをなんとなく集めたとか。。。• 寸評 – 自分がいい思っても、 他人からは意味が分からない感じ – 凝集のレベルとしては、・・・もっとも低い
  23. 23. 論理的凝集• 似た機能が集まっているが、 よく見ると異なる機能が1つのモジュールに含まれている。• 機能種別(フラグなど)をパラメータで指定して、 実は複数の機能を提供しているような場合• 寸評 – よく見かけるけど、if文がいっぱい。 (残念な感じがするプログラム。凝集度も低い) – 機能種別が増えると収集がつかなくなる。 – 機能追加は正しく動いているソースを修正することになりやすい • � オープン・クローズドの原則 (Open-Closed Principle) – private メソッドで、種別が on・off だけなら効果的な場合もある • � DRY - Dont Repeat Yourself.
  24. 24. 時間的凝集• ある時にまとめて実行する処理をまとめている – 「初期処理」 とか  「エラー処理」 とかをまとめたモジュール のような感じ• 別名 – 一時的凝集• 寸評 – 凝集のレベルとしてはそんなに高くないけど 効果的な場合あり • 同じような機能をいろんなところで作らないですむ。 • 近い箇所で実行するソースがまとまっていると、 ソースを理解しやすい
  25. 25. 手順的凝集• 複数の機能を実施する順番を取りまとめる• でも、共通したデータを扱ってない• 別名 – 手続き的凝集• 寸評 – 時間的凝集より、「順番」という概念を気にしている分、凝集度 高い – GoFの Facade パターン って、これに近い • 複雑な手続きを一箇所に集めるパターン
  26. 26. 通信的凝集• 関係あるデータ使って、 いくつかの機能を実行するモジュール• 機能の順序はあまり意味がない• 後述の逐次的凝集と分類しない場合もある• 別名 – 連絡的凝集• 寸評 – 凝集度高め – いいと思う
  27. 27. 逐次的凝集• 関係あるデータ使って、かつ、 実行する機能の順番に意味がある。 (通信的凝集かつ手順的凝集のようなもの)• 前述の通信的凝集と区別しない考え方もある• 別名 – 連絡的凝集• 寸評 – 凝集度はかなり高い
  28. 28. 機能的凝集• 1つの関連の強い機能をまとめたモジュール• 機能に必要なデータがある場合は – データのうち必要なものを機能として公開する• 例 – 1つのテーブルのI/Oに特化した機能・・・Daoですね• さらに分類することもある – 機能的強度 ・・・ 機能を重視 (凝集度最高) – 情報的強度 ・・・ データ重視• 寸評 – 凝集度は最強
  29. 29. •一通り説明してみました。。
  30. 30. •一通り説明してみました。。• でも正直なところ、 とおり一遍の説明では イメージが湧きません–(分類方法も何種類もあったり、似てたり するし)
  31. 31. •凝集度をイメージで捕らえて みようと思います
  32. 32. •まずは、 リファクタリングして、 凝集度が 低いものを高くする イメージ
  33. 33. 凝集度 低
  34. 34. 凝集度 低
  35. 35. 凝集度 低
  36. 36. 凝集度 高
  37. 37. • 関係が深い機能は1箇所に• 異なる機能は別々に• グチャグチャに絡まっているものをほぐす• 呼び出す側と呼び出される側は明確に – (コールバックなどは控えめにね)
  38. 38. • 次は、 新しい機能を追加した場合の モジュール改造 イメージ• 凝集度が 高い場合と、低い場合とを 比べます
  39. 39. 低い凝集のモジュール改造。。
  40. 40. 低い凝集のモジュール改造。。–白丸はモジュール–白丸の大きさはモジュールの規模–黒丸は改造–黒丸の大きさは改造の規模• イメージです
  41. 41. 低い凝集のモジュール改造。。
  42. 42. 高い凝集のモジュール改造 1
  43. 43. 高い凝集のモジュール改造 2
  44. 44. 高い凝集のモジュール改造 3
  45. 45. イメージでした
  46. 46. モジュールの凝集度 おわり
  47. 47. モジュールの結合度
  48. 48. モジュールの結合度• モジュールとモジュールが どのくらい強く結びついているか• 『疎結合』という言葉は 「モジュールの結合度」が低いということです• 疎結合を関係が深いキーワード「Webサービス」 – 「Webサービスにしたから疎結合」ではなく、 「疎結合なインタフェースでWebサービスを提供する」 であるべきです
  49. 49. モジュールの結合度 データ結合•• スタンプ結合 ↑ 結合度低い   良い• 制御結合• 外部結合• 共通結合• 内容結合 ↓ 結合度高い    悪い• どのぐらい、独立しているかの尺度
  50. 50. • 一通り説明します• 凝集度の説明よりは、 分かりやすいのではと思いますが、そんなに分かりやすくないです。• お付き合いください
  51. 51. 内容結合• 絶対番地を用いて直接相手モジュールを参照したり、相 手モジュールに直接分岐する• 寸評 – むしろ、『モジュール』とは呼んでいけないレベル – goto のある言語では、これができてしまう – Javaなど goto のない言語ではまずできない、 できたら逆に芸術的。
  52. 52. 共有結合• 共通領域(グローバル領域)に定義されたデータを参照する。• 寸評 – 結合度が高い。保守開発の影響度が広くて、改修しにくい。致命的 – マルチスレッドで予測不能の振る舞いをするリスクあり。 (安全に使えない) – Javaで見かけるパターン • staticフィールド、シングルトンオブジェクトを不用意に使ったもの • 大きなオブジェクトの参照を呼び出し先に渡しまくったり、 public でどこからでも参照できたりさせる – 正しく設計したシングルトンパターンオブジェクトでは使います。 • 属性を持たないロジックだけのシングルトンは、 共有結合とは関係ない。
  53. 53. 外部結合• 必要なデータだけを外部宣言し、ほかのモ ジュールから参照を許可し共有する。• 寸評 – 共有結合とほとんど同じ。改修しにくい。 • 利用する側が、使う項目を明確にして、 その項目以外使わなということが分類上違う模様 (でも、保守開発で影響度をきにしないといけなくなること は、ほとんど変わらないと思う。)
  54. 54. 制御結合• 機能コードなど、モジュールを制御する要素を引数 として相手モジュールに渡し、モジュールの機能や 実行を制御する。• モジュール凝集度の論理的凝集度がこれに相当 する。• 寸評 – 論理的凝集とおなじく、if文がいっぱいで、 よく見かけるけど残念なレベルです。 – 論理的凝集の繰り返しになりますが、 private メソッドで、種別が on・off だけなら効果的
  55. 55. スタンプ結合• 相手モジュールで、 構造体データ(レコード)の一部を使用する場合でも、 構造体データすべてを引数として相手モジュールに渡す• 寸評 – Daoで取得したテーブルのDTOをそのまま引数で渡すような 場合が該当する。必要な項目を限定すべきだが、面倒なので ついやってしまう。(プログラムを作るうえで面倒だという感覚 は重要でトレードオフの対象になると思う) – 引数を渡した先で書き換えられる危険を増やしていることに留 意する必要がある。(難解なバグになるかも) • � 防御的コピー.
  56. 56. データ結合• 相手モジュールをブラックボックスとして扱い、 必要なデータだけを引数として渡す。• 寸評 – 結合度は最も低い。 全部これにできることが理想 – 値渡しなら、呼び出し側で引数が変えられる心配なし – 参照(ポインタ)渡しの場合は、 引数を渡した先で書き換えられる危険性がある
  57. 57. •結合度も イメージで捕らえてみようと思 います
  58. 58. 結合度 強いA機能 B機能
  59. 59. 結合度 弱いA機能 B機能
  60. 60. A機能 B機能 インタフェースが コンパクト• パラメータと戻り値の項目数が少なくすれば、結合 度が低くなります(ざっくり言ってみました)
  61. 61. モジュールの結合度 おわり
  62. 62. •オブジェクト指向 について少し
  63. 63. 思い出そう:オブジェクト指向• オブジェクト指向といえば思いつくキーワード
  64. 64. 思い出そう:オブジェクト指向• オブジェクト指向といえば思いつくキーワード – カプセル化 – 継承 (インヘリタンス) – ポリモフィズム、・・・• でも、一番大事なことは。。。
  65. 65. 思い出そう:オブジェクト指向• 『データ』と『処理』を 一まとまりにする• メッセージの協調(連続)で、 機能を実現
  66. 66. 思い出そう:オブジェクト指向• 『データ』と『処理』を一まとまりにする – データ • 意味のあるデータの集まり – 処理 • メッセージとかメソッドとかサービスとか呼ばれるもの• メッセージの協調(連続)で、機能を実現 – オブジェクトからオブジェクトへ、 (短い)メッセージを送る行為が繰り返され、 全体の機能を実現する。 – メッセージを送る ≒ メソッドを呼び出す
  67. 67. 思い出そう:オブジェクト指向• 『データ』と『処理』を一まとまりにする – データ 機能的凝集 • 意味のあるデータの集まり 高い凝集度 – 処理 • メッセージとかメソッドとかサービスとか呼ばれるもの。• メッセージの協調(連続)で、機能を実現 – オブジェクトからオブジェクトへ、 (短い)メッセージを送る行為が繰り返され、 スタンプ結合 全体の機能を実現する。 データ結合 – メッセージを送る ≒ メソッドを呼び出す 低い結合度
  68. 68. 思い出そう:オブジェクト指向• オブジェクト指向って、 –凝集度を高くし、 –結合度を下げる設計手法です。
  69. 69. いつも使っているJavaって、オブジェクト思考ですか?(使ってない人も使ってることにしといてください)
  70. 70. オブジェクト指向設計 とは言いにくいケース• クラスにstaticメソッドしかない – ユーティリティライブラリ• フィールドとgetterとsetterしかない – データトランスファーオブジェクト(DTO)• メソッドはあるがフィールドが1つもない – サーブレットクラス、 シングルトンのビジネスロジック、 ステートレスBean(EJB)
  71. 71. オブジェクト指向で全部作ら なくてもいいけど・・• オブジェクト指向、全然使ってないように感じます• DTO、や、StrutsのFormにちょっと編集メソッドを加える と、オブジェクト思考っぽくなります。 (すごく簡単。手始めとしてはオススメ) – getPrice() ==> "10000" – getPriceForView() ==> "10,000 -" • こっちのほうが、タグを使うより簡単にコードの重複が減らせるます – � DRY (Dont Repeat Yourself.)
  72. 72. ぜひ、オブジェクト指向 を 見直してみて ください
  73. 73. インタフェース
  74. 74. どんなインタフェースが良いのか• 結合度をを低くする – 引数はすくない方がよい。引数なしが最も低い • DTOを渡すのは引数をたくさん渡すのと同じ • 機能を実現するための必要最小限の引数を• 返却値は(できれば)凝集度を高く – こちらはそんなにがんばらなくてもいいと思います• インタフェースで使う人が機能を想像できる – � 驚き最小の原則• 「作りやすいから」ではなく「使いやすいから」で決める – � TDD(Test Driven Development) - 作る前に使え
  75. 75. インタフェースを重要視する• 契約プログラミング (契約による設計) – 『事前条件』『事後条件』『不変条件』を明らかに – インタフェースは使う側の持ち物。 作り手側の都合で簡単に変えてはいけない。• 条件を明らかにするコツ – 条件をシンプルに。そのためには。。。 (繰り返しですが) • 凝集度を高める • 結合度を低くする
  76. 76. 良いインタフェースにするためのコツ• 今からあげるポイントに気をつけてJavadoc(かそれに近いドキュメント)を書いてください。そうすると、凝集度が高くなり結合度が低くなります
  77. 77. Javadocを書いてください• クラスを説明する• データが取得できない場合何が起こるか• 取得想定されるレコードは何件かを意識する• 想定外の件数を取得したら?• ソートするの?• 引数は必須?任意?• 例外とその意味は• 引数が本当に必要か
  78. 78. •本日言いたいこと (結論)に 戻ってきました
  79. 79. •個別のポイントに コメントしていきます
  80. 80. •が、そのまえに
  81. 81. 全部Javadoc書くのは面倒です。。。• 以下のような部分を優先して Javadocを書くのをオススメします。 – protected 以上のクラスとメンバーに – より重要な機能が記述されているクラスに • 「サービス」とか「ビジネスロジック」とか 「Model(MVCパターンのM)」とか 呼ばれるクラス
  82. 82. •個別のポイントに コメントしていきます
  83. 83. クラスを説明する• 何の機能かを簡潔に書きます(1文で何者なのかを表現 できればより良い) – 説明に合致しない機能が定義されていませんか。 詰め込みすぎではないですか – 説明した機能を実現していますか• ポイント – 説明できなければ設計がおかしいのかも – 凝集度が低いとうまく説明できません
  84. 84. データが取得できない場合 何が起こるか• 返却例 – NULL – 空のリスト – 例外 – Nullオブジェクトパターン のオブジェクト• ポイント – 『事後条件』を明らかにしてください
  85. 85. 取得想定されるレコードは何件かを意識 する• まず、1件返却なのか複数件返却なのかを明確に – 1件なら、Listや配列を返してはいけない – 複数件なら返却件数を意識してください。 • 20件程度、 1000件程度、 とてつもなく多い – 返却件数に限界があるのならドキュメントに明示してください • システム的に限界は • 運用的に限界は• ポイント – 『事前条件』『事後条件』を明らかにしてください
  86. 86. 想定外の件数を取得したら?• 考えていないはだめ、明示することが大切 – 例外? – falseを返却する? – 先頭n件を返却する – その他具体的に• ポイント – 『事後条件』を明らかにしてください
  87. 87. ソートするの?• ソートするなら、ソートキーを明示してください。• 複数件返すのにソートしないのであれば、 順番が保証されないことを明記してください。• ポイント – 『事後条件』を明らかにしてください
  88. 88. 引数は必須?任意?• 任意なパラメータを避ける – 「オーバーロード」とか「デフォルト引数」とかを使って• 任意はパラメータを用意する場合は、 設定するか否かで何起こるか明記してください• どれが必須で、どれが任意か明示してください• ポイント – 結合度を低くしてください。 • 任意なパラメータは実質的に制御結合(結合度が高い)になっている 可能性があります – 複数任意なパラメータがあると、 組み合わせの数は爆発的に増えて説明困難になる
  89. 89. 例外の意味は• スローする例外の意味を説明してください – ドメイン上の意味がある異常 • 意味ある例外を作ってスロー – 処理の継続ができない異常 • 汎用的のランタイム例外をスローするのがいいケースが多い – バグ、環境障害、のケースはこれ• 例外がない言語の場合、呼び出し元に異常を伝える方 法を明示する• ポイント – 『事後条件』を明らかにしてください
  90. 90. 引数が本当に必要か• メソッド内で使っていない引数は無いですか• DTOを渡すのは、引数をたくさん渡していることと 同じです。• 引数にとらなくても、 メソッド内で何とかならないか考える。 – 何とかなるなら、引数にすべきか否か再考する• ポイント – 結合度を低くしてください – � KISSの原則 (Keep it simple, stupid. or Keep it short and simple.)
  91. 91. 個別のポイント おわり
  92. 92. 最後にケーススタディーを少しやります
  93. 93. ケーススタディー:引数検討• ケース –「キー1」を渡して情報を受け取る 「WebサービスA」の クライアントを作る <<DFD図>> サービス キー1 A 取得結果
  94. 94. ケーススタディー:引数検討• インタフェース1 – 引数 • キー1• インタフェース2 – 引数 • キー1 • WebサービスのURL
  95. 95. ケーススタディー:引数検討• Webサービスクライアントの本質を考えてみる – 重要なのは、「キー1」を渡して情報をうけとること – WebサービスのURLは重要でない。 • 変わってもいいもの • 開発環境によって変わりそう • テストでは、テスト用のURLを使いたくなりそう
  96. 96. ケーススタディー:引数検討• インタフェース1 – 引数 • キー1• インタフェース2 – (インタフェースはコンパクトにと説明しましたが、 こちらをオススメします) – 引数 • キー1 • WebサービスのURL• インタフェース1を作りたい場合、 インタフェース2 を呼び出して作ればいい
  97. 97. インタフェース おわり
  98. 98. おわりに• プログラミングは感覚が大事だと思います。• 感覚を磨くには、 – たくさんコードを読む – たくさんコードを書く – 先人のノウハウを吸収する – そして、よく考える• 地道な積み上げ大事
  99. 99. • 今日の勉強会の内容が、 今後の皆さんの何らかのきっかけ になってくれたら幸いです
  100. 100. ご清聴ありがとう ございました

×