Application Design 勉強会 #4
Application Design勉強会13-15章Wed Jul 17Kazuki Chigita
View Slide
はじめに• 第3部の意義• デザインパターンを学ぶ.
今⽇話すこと• Commandパターン• ActiveObjectパターン• TemplateMethodパターン• Strategyパターン• Facadeパターン• Mediatorパターン
Commandパターン• 以下のようなinterfaceを用意する.• 利用するときはCommandを実装する.• 何がうれしいの?• この構造にすれば,Commandの実装クラスの詳細を知らずとも利用できる.• do()をすれば全てのコマンドが操作できる.
Commandパターン• 以下のようなinterfaceを用意する.• 利用するときはCommandを実装する.• 何がうれしいの?• この構造にすれば,Commandの実装クラスの詳細を知らずとも利用できる.• do()をすれば全てのコマンドが操作できる.シンプルなCommandパターンではメソッドは⼀つ
Commandパターン• 以下のようなinterfaceを用意する.• 利用するときはCommandを実装する.• 何がうれしいの?• この構造にすれば,Commandの実装クラスの詳細を知らずとも利用できる.• do()をすれば全てのコマンドが操作できる.シンプルなCommandパターンではメソッドは⼀つそれぞれでdo()をoverrideする.
Commandパターン(例1)• Transactionでの利用• 使う側は同様にTransactionを実装(override)• メリット1 : ビジネスロジックとチェック機構の分離• メリット2 : 一時保存 / 時間差実行の実現
Commandパターン(例1)• メリット1 : ビジネスロジックとチェック機構の分離• validate() はGUI等からも使われる有効性のチェックが具体的な登録処理を含むのは危ない.• validate()はデータベースの詳細を知ることがないので,ここでも分離ができている.• メリット2 : 一時保存 / 時間差実行の実現• validate()の後,すぐにexecute()を呼び出す必要はない.• execute()だけバッチ処理的に時間差で実行してもなんの問題もない.• 分離することで,一時的に状態を保持しておく構造ができている.
Commandパターン(例2)• Undo機構の実現• Commnadの実装先でdo()の処理内容を記憶する必要がある.• undo()はdo()に依存しているので抱き合わせて実装を考える必要がある.
Commandパターンまとめ• 普通はクラスに多くのpublic methodをもたせるがそうではなくごく少数に抑えることで,見通しを良くする.• interfaceの中に複数のメソッドを入れても,その存在意味を分離させたり(Transactionの例),抱き合わせたり(Undoの例)できる.
ActiveObjectパターン• Commandパターンの利用例• イベント駆動型やマルチスレッドを実現するためのパターンActiveObjectEngine : Commandのリストを持ち,これらの実⾏を管理するCommand : Interface.Commandパターン.SleepCommand: Commandの実装クラス
ActiveObjectパターン
ActiveObjectパターンActiveObjectEngineitsCommandsSleepComandHogeComand (wakeupCommandとして持っていると仮定)
ActiveObjectパターンActiveObjectEngineitsCommandsSleepComandSleepTimeの間これを繰り返す.HogeComand (wakeupCommandとして持っていると仮定)
ActiveObjectパターンActiveObjectEngineitsCommandsSleepComandSleepTimeの間これを繰り返す.HogeComand (wakeupCommandとして持っていると仮定)SleepTimeが終わったらこっちが登録される.
ActiveObjectパターンまとめ• 本来はブロッキング処理等で処理を止めて,itsCommandsを複数のスレッドにわたしてあげると簡易的なマルチスレッド処理に実現ができる.• イベント駆動型の真髄はこういうパターンだ.• Commandパターンをうまく活用している例.
TemplateMethodパターン• 課題 : 似た処理がアチラコチラに出てくる.パターン化した処理がコピペで煩雑に使われている.• 解決法• 共通化や概念化できる大きな枠としての処理をabstract class(抽象基本クラス)に持っていく.• 上の概念化されたクラスを継承先で具体的なクラス実装を行う.• 例 : Bubble Sortをどう扱うか
TemplateMethodパターン• BubbleSorter という abstractクラスを作成し,ここに大枠の実装の処理を委ねる.• これを継承するクラスで詳細を実装することで共通化を図る.BubbbleSorter{abbstract}IntBubbbleSorterDoubleBubbbleSorter
TemplateMethodパターン• 問題点• BubbleSorterという名前にしてることからも分かる通り,swap(index: Int)や,outOfOrder(index: Int)は,他のアルゴリズムで利用できない.• BubbleSortのための再利用性はあるが,他アルゴリズムのために使うことができない.
Strategyパターン• 課題 : 似た処理がアチラコチラに出てくる.パターン化した処理がコピペで煩雑に使われている.(TemplateMethodパターンと同じ)• 解決法• 汎用的な部分や概念的な部分を抽象クラスで実装せずに,Handleクラスのようなものに持っていく• 実装すべきものはinterfaceに切り出す• 例 : Bubble Sortをどう扱うか
Strategyパターン• 良い点• TemplateMethodパターンの課題を解決している.• SortHandleを他のソートパターンでも利用できる• interfaceで切り出しているので,DIPと相性がいい.• BubbleSortのみにとどまらない再利用性が高い.• 問題点• 実装が少し多くなる• (こういうパターンはStrategyパターンで解決するのが現状良さそう)
Facade & Mediator パターン• 課題 : クラス間の結合度を下げたい.• 解決方法• Façade• 上から抑える(wrapする)• Mediator• 下から抑える(Mediatorにやってもらう)
Facadeの場合P224 図15-1より
Facadeの場合P224 図15-1より集約点を作る
Mediatorの場合
使い分け• FacadeとMediatorの使い分け• 明示的に方針を示したいとき.集約点を作りたいとき→Façade• 非明示的に方針を課したいとき→Mediator