Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

• パッケージ設計の原則 • 再利⽤・リリース等価の原則(REP) • 全再利⽤の原則(CRP) • 閉鎖性共通の原則(CCP) • ⾮循環依存関係の原則(ADP) • 安定依存の原則(SDP) • 安定度・抽象度等価の原則(SAP) • Factoryパターン 今日話すこと

Slide 3

Slide 3 text

• パッケージを考慮した設計が何故 求められるのか? • ソフトウェアアプリケーションの規模が⼤きく・ 複雑になるとそれを上⼿に体系化する必要がある. • これはクラスよりも⼤きな枠組みであり,これを 「パッケージ」と呼ぶ • KotlinのPakageやいわゆるmodule等を考えるといい. • SOLID原則のように体系だった理論がある. • ここではそれを学ぼうね. 導入

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

• パッケージ内部の凝集度に関する原則 • 再利⽤・リリース等価の原則(REP) • 全再利⽤の原則(CRP) • 閉鎖性共通の原則(CCP) • パッケージ同⼠の結合度や安定性に関する原則 • ⾮循環依存関係の原則(ADP) • 安定依存の原則(SDP) • 安定度・抽象度等価の原則(SAP) 6原則 様々な指標があるが一言で表すとするなら, モジュールがどの程度たった一つの機能に 特化しているのかを考える尺度(メトリクス)

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

• 閉鎖性共通の原則 (CCP : Common Closure Principle) • パッケージに含まれるクラスはみな同じ種類の変更 に対して閉じているべき. • つまり,パッケージに影響する変更はパッケージ内の すべてのクラスに影響を及ぼすが,他のパッケージには 影響しない. • 単⼀責任の原則(SPR)のパッケージ版といえる. • クラスの変更理由を複数持ってはいけないのと同様に, パッケージもまた変更の理由は唯⼀つであるべきである と主張している. 閉鎖性共通の原則

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

• 凝集度は今の3つの原則を以て議論される. 凝集度に関する原則の再考 REP 再利用のため のグループ化 CRP CCP 保守性のため のグループ化 不要なリリース作業を 減らすための分割 互いに反する理念に基づいている部分もあるので 総合的にみて凝集度を評価するべき

Slide 11

Slide 11 text

• 問題提起 • パッケージの依存関係をグラフとみなしたときに 循環してはならない. • ⼀⼈で作っていたらこの現象は起きにくいが複数⼈ でやってると起きることがある(それは時にビルド が通らないといった問題を引き起こす) • この問題を解決するために「ウィークリービルド」 と「⾮循環依存関係の原則(ADP)」がある. • ウィークリービルド • 週のうち4⽇間は開発者お互いの開発のパッケージ の依存等を気にせず開発を進め,最期の⼀⽇で すべての変更を統合しシステムをビルドするやり⽅. • 規模が⼤きくなるについれて統合のコストがでかく なる(それはそう) 非循環依存関係の原則

Slide 12

Slide 12 text

• ⾮循環依存関係の原則 (ADP : Acyclic Dependencies Principle) • 開発環境をリリース可能なパッケージに分割する. (つまりパッケージは仕事の単位となる) • あるパッケージに対して開発者を割り当て, リリース可能な状態になったらリリースする. • パッケージを追加するときは各パッケージをグラフ のノードと⾒たときにDAGになるように追加する. • 閉路を作ってしまうとそれ全体が結果的に依存し⼀つの 巨⼤なパッケージと化してしまうので避けるべき. • システム全体をリリースするときは末端のノードか らボトムアップにリリースする. 非循環依存関係の原則

Slide 13

Slide 13 text

• 循環を⽣じないようにパッケージを処理する例 • 現在のパッケージ構成が以下のようになっている. 非循環依存関係の原則 p321 図20-1より

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

• 循環を⽣じないようにパッケージを処理する例 • 何も考えずこれをやってしまうと,以下の図のよう になる. • MyApplication – MyTasks – MyDailogsが閉路を⽣んで おり,これらが強く依存してしまう. • DAGに変換する必要がある. 非循環依存関係の原則 p322 図20-2より

Slide 17

Slide 17 text

• 循環を⽣じないようにパッケージを処理する例 • DAGを殺すアイデアとしては以下の⼿順である. 1. ⽮印の⽅向を逆転させる. 2. 新しいパッケージを⽣む. 1. ⽮印の⽅向を逆転させる • MyDialogsが利⽤するインタフェースを抽象クラスとして MyDialogsに持たせ,MyApplicationsがそれを実装するよう にする(依存関係逆転の原則 : DIP) 非循環依存関係の原則 p323 図20-3より Before After

Slide 18

Slide 18 text

• 循環を⽣じないようにパッケージを処理する例 2. 新しいパッケージを⽣む • MyDialogsとMyApplicationsが両⽅とも依存するようなパッ ケージを追加する. • 以上の⼿順を以てDAGをなくした.DAGはこの⼿順 で必ずなくすことができる. 非循環依存関係の原則 p324 図20-4より

Slide 19

Slide 19 text

• 安定依存の原則 (SDP : Stable Depndencies Principle) • 安定する⽅向に依存せよ. • 特定の種類の変更に敏感なパッケージ(A)を考えた ときにこのパッケージが変更が難しいパッケージ (B)に依存されると途端に(A)の変更が難しくなって しまう.→このような問題を解決する. • 安定性とは? • 直感的には以下. • 多くのパッケージによって参照されているパッケージは 変更が難しい→安定している(外部要因によって変更がさ れにくい) • 他のパッケージから参照されていないパッケージは変更 が容易→不安定(外部要因によっての変更が簡単) 安定依存の原則

Slide 20

Slide 20 text

• 定量的に⽰す. • " (内側に向かう結合度) : このパッケージの外にあり, このパッケージの中にあるクラスに依存するクラス の数 • # (外側に向かう結合度) : このパッケージの中にあり, このパッケージの外にあるクラスに依存するクラス の数 • (不安定度) : = &' &()&' • が0のときは安定度が最⼤であり.⾃⾝は他に依存しない. • が1のときは最も不安定であり,責任がない. • この定量評価を⽤いて原則を⾔い直すと, 「パッケージAの不安定度 はそれが依存する パッケージBの不安定度 より⼤きくあるべき」 と⾔っている. • もしも逆転している場合はDIPによって解決. 安定依存の原則

Slide 21

Slide 21 text

• 安定度・抽象度等価の原則 (SAP : Stable Abstractions Principle) • 安定度の⾼いパッケージはその拡張性を失わないた めに抽象的でなければならない. • 逆に,不安定なパッケージは具体的でなければなら ない.不安定であれば具体的なコードを簡単に変更 することができるから. • 抽象度を定義する. • . : パッケージ内のクラスの数 • / : パッケージ内の抽象クラスの数 • 抽象度 ∶ = 3( 34 安定度・抽象度等価の原則

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

• 主系列からの距離を[0,1]に正規化し,標準偏 差を⽰す. • 著者いわく ≥ 1は例外的なのか,問題があるのか の⼆択なのでここを治していくとよい. • それが安定度・抽象度等価(SAP)に従うということ. 安定度・抽象度等価の原則 p335 図20-14より 距離 = 9):;< =

Slide 25

Slide 25 text

• 抽象インターフェースだけを利⽤して具体的な クラスのインスタンスを⽣成することを可能に する. • 開発途上の具体的なクラスがまだ⾮常に不安定なと きに⼤きな助けとなる. • これを使うことで,具体的なクラスの作成に依存す ることなく,factoryだけへの依存が可能になる. • メリット : Factoryを⼊れ替えるだけ(中の実装を変え るだけ)で,アプリケーションで利⽤するオブジェ クトを変えることができる(実装交換可能性) Factoryパターン

Slide 26

Slide 26 text

• ⾮factoryパターンをfactoryにする • こうすると,SomeAppがSquareやCircleを直接知るこ とがなくなる(具体的な依存をしない) Factoryパターン

Slide 27

Slide 27 text

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