Pro Yearly is on sale from $80 to $50! »

Application Design 勉強会 #6

Application Design 勉強会 #6

パッケージ設計論
パッケージ設計の原則
再利用・リリース等価の原則(REP)
全再利用の原則(CRP)
閉鎖性共通の原則(CCP)
非循環依存関係の原則(ADP)
安定依存の原則(SDP)
安定度・抽象度等価の原則(SAP)

Factoryパターン

A445824f9bb334ec104f5c1c7b67fee2?s=128

Kazuki Chigita

July 24, 2019
Tweet

Transcript

  1. Application Designษڧձ #6 20-21ষ Wed Jul 24 Kazuki Chigita

  2. • パッケージ設計の原則 • 再利⽤・リリース等価の原則(REP) • 全再利⽤の原則(CRP) • 閉鎖性共通の原則(CCP) • ⾮循環依存関係の原則(ADP)

    • 安定依存の原則(SDP) • 安定度・抽象度等価の原則(SAP) • Factoryパターン 今日話すこと
  3. • パッケージを考慮した設計が何故 求められるのか? • ソフトウェアアプリケーションの規模が⼤きく・ 複雑になるとそれを上⼿に体系化する必要がある. • これはクラスよりも⼤きな枠組みであり,これを 「パッケージ」と呼ぶ •

    KotlinのPakageやいわゆるmodule等を考えるといい. • SOLID原則のように体系だった理論がある. • ここではそれを学ぼうね. 導入
  4. • パッケージ内部の凝集度に関する原則 • 再利⽤・リリース等価の原則(REP) • 全再利⽤の原則(CRP) • 閉鎖性共通の原則(CCP) • パッケージ同⼠の結合度や安定性に関する原則

    • ⾮循環依存関係の原則(ADP) • 安定依存の原則(SDP) • 安定度・抽象度等価の原則(SAP) 6原則
  5. • パッケージ内部の凝集度に関する原則 • 再利⽤・リリース等価の原則(REP) • 全再利⽤の原則(CRP) • 閉鎖性共通の原則(CCP) • パッケージ同⼠の結合度や安定性に関する原則

    • ⾮循環依存関係の原則(ADP) • 安定依存の原則(SDP) • 安定度・抽象度等価の原則(SAP) 6原則 様々な指標があるが一言で表すとするなら, モジュールがどの程度たった一つの機能に 特化しているのかを考える尺度(メトリクス)
  6. • 再利⽤・リリース等価の原則 (REP : Reuse-Release Equivalency Principle) • REPは再利⽤の単位(つまりパッケージ)がリリース の単位よりも⼩さくなることはない

    . • つまり再利⽤されるもの(パッケージ)はリリース・ トラッキングされなければならない. • 砕いた説明をするとパッケージを更新するときはリリー スされる必要がある. • あるリリースでのパッケージ(クラス群)を再利⽤す るか / しないかを決められるようにするべきという ことを⾔いたい. • Javaの例を上げると各リリースでjarファイルが吐き出され, 特定のクラスを使うのではなくそのjarを使うべき. 再利用・リリース等価の原則
  7. • 全再利⽤の原則 (CRP : Common Reuse Principle) • パッケージに含まれるクラスは,すべて⼀緒に 再利⽤される.

    • つまり,パッケージに含まれるいずれかのクラスを 再利⽤するということは,その他のクラスもすべて 再利⽤することを意味する. • もっと砕いて⾔うならば,⼀緒に使われる傾向のあるク ラスは同じパッケージに属する. • これはつまり,同⼀パッケージにあるものはクラス 間に強い依存関係があるとも⾔える. <=> クラス間に依存関係がないものは同⼀パッケー ジにするべきではない. 全再利用の原則
  8. • 閉鎖性共通の原則 (CCP : Common Closure Principle) • パッケージに含まれるクラスはみな同じ種類の変更 に対して閉じているべき.

    • つまり,パッケージに影響する変更はパッケージ内の すべてのクラスに影響を及ぼすが,他のパッケージには 影響しない. • 単⼀責任の原則(SPR)のパッケージ版といえる. • クラスの変更理由を複数持ってはいけないのと同様に, パッケージもまた変更の理由は唯⼀つであるべきである と主張している. 閉鎖性共通の原則
  9. • 凝集度は今の3つの原則を以て議論される. 凝集度に関する原則の再考 REP 再利用のため のグループ化 CRP CCP 保守性のため のグループ化

    不要なリリース作業を 減らすための分割
  10. • 凝集度は今の3つの原則を以て議論される. 凝集度に関する原則の再考 REP 再利用のため のグループ化 CRP CCP 保守性のため のグループ化

    不要なリリース作業を 減らすための分割 互いに反する理念に基づいている部分もあるので 総合的にみて凝集度を評価するべき
  11. • 問題提起 • パッケージの依存関係をグラフとみなしたときに 循環してはならない. • ⼀⼈で作っていたらこの現象は起きにくいが複数⼈ でやってると起きることがある(それは時にビルド が通らないといった問題を引き起こす) •

    この問題を解決するために「ウィークリービルド」 と「⾮循環依存関係の原則(ADP)」がある. • ウィークリービルド • 週のうち4⽇間は開発者お互いの開発のパッケージ の依存等を気にせず開発を進め,最期の⼀⽇で すべての変更を統合しシステムをビルドするやり⽅. • 規模が⼤きくなるについれて統合のコストがでかく なる(それはそう) 非循環依存関係の原則
  12. • ⾮循環依存関係の原則 (ADP : Acyclic Dependencies Principle) • 開発環境をリリース可能なパッケージに分割する. (つまりパッケージは仕事の単位となる)

    • あるパッケージに対して開発者を割り当て, リリース可能な状態になったらリリースする. • パッケージを追加するときは各パッケージをグラフ のノードと⾒たときにDAGになるように追加する. • 閉路を作ってしまうとそれ全体が結果的に依存し⼀つの 巨⼤なパッケージと化してしまうので避けるべき. • システム全体をリリースするときは末端のノードか らボトムアップにリリースする. 非循環依存関係の原則
  13. • 循環を⽣じないようにパッケージを処理する例 • 現在のパッケージ構成が以下のようになっている. 非循環依存関係の原則 p321 図20-1より

  14. • 循環を⽣じないようにパッケージを処理する例 • 現在のパッケージ構成が以下のようになっている. • ここでMyDialogsがMyApplication内のクラスを利⽤ するケースを考える. 非循環依存関係の原則 p321 図20-1より

  15. • 循環を⽣じないようにパッケージを処理する例 • 何も考えずこれをやってしまうと,以下の図のよう になる. 非循環依存関係の原則 p322 図20-2より

  16. • 循環を⽣じないようにパッケージを処理する例 • 何も考えずこれをやってしまうと,以下の図のよう になる. • MyApplication – MyTasks –

    MyDailogsが閉路を⽣んで おり,これらが強く依存してしまう. • DAGに変換する必要がある. 非循環依存関係の原則 p322 図20-2より
  17. • 循環を⽣じないようにパッケージを処理する例 • DAGを殺すアイデアとしては以下の⼿順である. 1. ⽮印の⽅向を逆転させる. 2. 新しいパッケージを⽣む. 1. ⽮印の⽅向を逆転させる

    • MyDialogsが利⽤するインタフェースを抽象クラスとして MyDialogsに持たせ,MyApplicationsがそれを実装するよう にする(依存関係逆転の原則 : DIP) 非循環依存関係の原則 p323 図20-3より Before After
  18. • 循環を⽣じないようにパッケージを処理する例 2. 新しいパッケージを⽣む • MyDialogsとMyApplicationsが両⽅とも依存するようなパッ ケージを追加する. • 以上の⼿順を以てDAGをなくした.DAGはこの⼿順 で必ずなくすことができる.

    非循環依存関係の原則 p324 図20-4より
  19. • 安定依存の原則 (SDP : Stable Depndencies Principle) • 安定する⽅向に依存せよ. •

    特定の種類の変更に敏感なパッケージ(A)を考えた ときにこのパッケージが変更が難しいパッケージ (B)に依存されると途端に(A)の変更が難しくなって しまう.→このような問題を解決する. • 安定性とは? • 直感的には以下. • 多くのパッケージによって参照されているパッケージは 変更が難しい→安定している(外部要因によって変更がさ れにくい) • 他のパッケージから参照されていないパッケージは変更 が容易→不安定(外部要因によっての変更が簡単) 安定依存の原則
  20. • 定量的に⽰す. • " (内側に向かう結合度) : このパッケージの外にあり, このパッケージの中にあるクラスに依存するクラス の数 •

    # (外側に向かう結合度) : このパッケージの中にあり, このパッケージの外にあるクラスに依存するクラス の数 • (不安定度) : = &' &()&' • が0のときは安定度が最⼤であり.⾃⾝は他に依存しない. • が1のときは最も不安定であり,責任がない. • この定量評価を⽤いて原則を⾔い直すと, 「パッケージAの不安定度 はそれが依存する パッケージBの不安定度 より⼤きくあるべき」 と⾔っている. • もしも逆転している場合はDIPによって解決. 安定依存の原則
  21. • 安定度・抽象度等価の原則 (SAP : Stable Abstractions Principle) • 安定度の⾼いパッケージはその拡張性を失わないた めに抽象的でなければならない.

    • 逆に,不安定なパッケージは具体的でなければなら ない.不安定であれば具体的なコードを簡単に変更 することができるから. • 抽象度を定義する. • . : パッケージ内のクラスの数 • / : パッケージ内の抽象クラスの数 • 抽象度 ∶ = 3( 34 安定度・抽象度等価の原則
  22. • 不安定度と抽象度でグラフを作ることを考 える. • 苦痛ゾーン : 抽象度が低く安定(具体実装に強く依存 される)領域 • 無益ゾーン

    : 抽象度が⾼く不安定(依存するパッケー ジがない抽象クラスに意味はない) 安定度・抽象度等価の原則 p333 図20-13より
  23. • 不安定度と抽象度でグラフを作ることを考 える. • 苦痛ゾーン : 抽象度が低く安定(具体実装に強く依存 される)領域 • 無益ゾーン

    : 抽象度が⾼く不安定(依存するパッケー ジがない抽象クラスに意味はない) 安定度・抽象度等価の原則 p333 図20-13より この付近に散らばるべきっぽい
  24. • 主系列からの距離を[0,1]に正規化し,標準偏 差を⽰す. • 著者いわく ≥ 1は例外的なのか,問題があるのか の⼆択なのでここを治していくとよい. • それが安定度・抽象度等価(SAP)に従うということ.

    安定度・抽象度等価の原則 p335 図20-14より 距離 = 9):;< =
  25. • 抽象インターフェースだけを利⽤して具体的な クラスのインスタンスを⽣成することを可能に する. • 開発途上の具体的なクラスがまだ⾮常に不安定なと きに⼤きな助けとなる. • これを使うことで,具体的なクラスの作成に依存す ることなく,factoryだけへの依存が可能になる.

    • メリット : Factoryを⼊れ替えるだけ(中の実装を変え るだけ)で,アプリケーションで利⽤するオブジェ クトを変えることができる(実装交換可能性) Factoryパターン
  26. • ⾮factoryパターンをfactoryにする • こうすると,SomeAppがSquareやCircleを直接知るこ とがなくなる(具体的な依存をしない) Factoryパターン

  27. • ロバート・C・マーチン他. アジャイルソフトウェア開発の奥義第2版 オブジェクト指向開発の神髄と匠の技. SBクリエイティブ,2008 参考文献