システム分析の成果物を入力として、また機能外要求を踏まえて、分析オブジェクトを詳細化する。 このIterationで重要となる機能外要求は、
Puzzle Frameworkにおける、モデルの仕様は以下のようになっている。
オペレーション | アクセス | 説明 |
---|---|---|
lastModifiedPos | public | ユーザーにより変更されたセルの位置を返す。 |
isModified | public | 盤面がユーザーにより変更されているかどうかを返す。 |
flush | public | 変更された位置をリセットする。 |
getCurStateAt | public | 指定された位置のセルの状態を取得する。 |
nextStateAt | public | 指定された位置のセルの状態を次の状態に遷移させる。 |
prevStateAt | public | 指定された位置のセルの状態をひとつ前の状態に遷移させる |
createBoard | public | 指定されたサイズの盤面を構築する。 |
initProblemAt | public | 指定された問題レコードを盤面に割り当てる。 |
setProblem | public | 指定された問題を読み込み、盤面に反映させる。 |
contains | public | 指定された位置が盤面内かどうかチェックする。 |
isNumberAt | public | 指定された位置のセルの状態が数字状態であるかどうかチェックする。 |
isSpaceAt | public | 指定された位置のセルの状態が空白状態であるかどうかチェックする。 |
isTransitAt | public | 指定された位置のセルの状態が遷移できるかどうかチェックする。 |
getHeight | public | 盤面の高さを取得する。 |
getWidth | public | 盤面の幅を取得する。 |
getSize | public | 盤面のサイズを取得する。 |
Frameworkにおいて、このモデルをDecoratorのパターンを適用し、階層化することで、 モデルの責務を小さくするようにしている。階層化を容易にするため、 Frameworkでは、抽象クラスAbstractdecorationModeを用意している。
オペレーション | アクセス | 説明 |
---|---|---|
nextStateAtSelf | protected | 指定された位置のセルの状態を次の状態に遷移させる。 |
prevStateAtSelf | protected | 指定された位置のセルの状態をひとつ前の状態に遷移させる |
createBoardSelf | protected | 指定されたサイズの盤面を構築する。 |
initProblemAtSelf | protected | 指定された問題レコードを盤面に割り当てる。 |
lastModifiedSelf | protected | ユーザーにより変更されたセルの位置を返す。 |
isModifiedSelf | protected | 盤面がユーザーにより変更されているかどうかを返す。 |
flushSelf | protected | 変更された位置をリセットする。 |
addModel | public | デコレート対象をModel階層の最下層に追加する。 |
getDecorated | protected | デコレート対象を取得する。 |
isAvailableEvent | protected | 指定されたStateEventCodeを受け入れることができるかどうかチェックする。 |
この仕様を元にフィルオミノにおける盤面情報の管理のRelationshipは、下図のような構成になった。
図:盤面情報の管理のクラス図
この図において、青く色図けられたクラスは、Frameworkに含まれるクラスである。 盤面の内部情報を管理するクラスBoardModelは、 ユーザーによる選択情報を管理するSelectionModelによってラップされていることを示している。
Frameworkの仕様に従って、状態遷移マネージャの実装を与える必要がある。 盤面の状態遷移は、空白から数字状態、または数字状態から別の数字状態、または数字状態から空白状態に絞られる。 選択状態は、既存の状態を選択状態でラップすればよいので、遷移マネージャには含めない。
図:盤面状態の遷移図
盤面状態の更新の挙動は、Frameworkでは現在定義されていないため、フィルオミノ専用のものを定義した。 下この挙動に対して、下表のコンポーネントと責務を与えた。
オペレーション | アクセス | 説明 |
---|---|---|
notifySelectionChanged | public | 盤面の特定領域を選択する。 |
notifyInputOccured | public | 選択された箇所に数字を入力する。 |
フィルオミノでは、ChangeHandlerを実装したクラスFilloChangeHandlerを定義した。
下図は、このコンポーネントのRelationshipを示している。
図:盤面状態の更新のクラス図
また、Modelに対して送信するStateEventCodeを実現したValueオブジェクトChangeEventとNumberInputEvent の仕様を下表に示す。
属性 | アクセス | 説明 |
---|---|---|
TYPE_SELECTION | public | 選択イベントタイプ。 |
mEventType | private | イベントタイプ。 |
mIsActivePos | private | アクティブポジションダルかどうかを示すフラグ。 |
属性 | アクセス | 説明 |
---|---|---|
mValue | private | アクティブポジションダルかどうかを示すフラグ。 |
ChangeEventやNumberInputEventは直接インスタンス化せず、Factory Method, ChangeEventFactoryを介して生成する。 このIterationの段階では、選択イベントと数字入力イベントのみを作成することができる。
オペレーション | アクセス | 説明 |
---|---|---|
createSelectionEvent | public | 選択イベントを作成する。 |
createNumberInputEvent | public | 数字入力イベントを作成する。 |
ChangeEventを取り巻くオブジェクトやクラスのRelationshipは、下図のようになった。
図:Valueオブジェクトのクラス図
問題の読み込み挙動も、Frameworkでは定義されていないため、フィルオミノ専用の定義を与えた。 この挙動に対して、下表のコンポーネントと責務を与えた。
オペレーション | アクセス | 説明 |
---|---|---|
loadProblem | public | 指定された問題を読み込む。 |
このコンポーネントの静的な構造とModelに対して送信するValueオブジェクト、ProblemInfoは frameworkで下表のように定義されている。
属性 | アクセス | 説明 |
---|---|---|
mFileName | private | 問題が保存されているファイル名。 |
mIndex | private | この問題のインデックス。 |
mWidth | private | 水平方向のセル数。 |
mHeight | private | 垂直方向のピース数。 |
mRecords | private | 各セルのRecordを格納するList。 |
フィルオミノでは、このインターフェースを実現したクラスFilloProblemLoaderを定義した。
このコンポーネントを取り巻くクラスとの間のRelationshipは下図のようになった。
図:問題の読み込みのクラス図
表示の更新挙動は、Frameworkで定義されているが、Modelに対してViewが直接アクセスしていることや、 FrameworkのRendererの責務の重さに違和感を感じていたため、再設計した。 もとのframeworkでは描画情報をRendererが管理しており、実際の描画はRenderer#renderから RenderListener#renderへ処理を委譲させることで行っていた。 再設計において、盤面の管理とRenderListenerの管理を分離させることに主眼を置いた。 また、ただ指定された状態を描画するのではなく、直接Model等から状態を取得し描画するようにした。 新設計では、この描画全般を管理するクラスとしてRenderStrategyを作成した。 これに伴い実際に描画を行うクラスをRenderListenerからRendererに変更し、 Rendererの管理、探索を行うクラスRendererLocatorを作成した。
結果、この挙動に対して、下表のコンポーネントと責務を与えた。
オペレーション | アクセス | 説明 |
---|---|---|
render | public | 描画を依頼する。 |
getRenderedImage | public | 描画したイメージを取得する。 |
installRenderer | public | 実際に描画を実行するRendererをRendererFactoryを介して登録する。 |
installDefaultRenderer | public | Backgroundの描画を行うRendererをRendererFactoryを介して登録する。 |
setBackground | public | Backgroundカラーをセットする。 |
setSize | public | 表示用のイメージサイズを変更する。 |
getBoardSize | public | 表示用のイメージサイズを取得する。 |
setPieceSize | public | 1セル区画のサイズをセットする。 |
getPieceSize | public | 1セル区画のサイズを取得する。 |
calcPortToBoardPos | public | スクリーンの座標からBoard条の座標に変換する。 |
getClipBounds | public | 再描画が行われるClipping領域を取得する。 |
RenderStrategyでは、システム分析で抽出された責務に加えて、表示領域の作成や取得などの責務を加えた。
オペレーション | 説明 |
---|---|
lookup | 指定された状態の対応するRendererを検索する。 |
addRenderer | 内部テーブルに状態をキーとするRenderを登録する。 |
installRenderer | 実際に描画を実行するRendererをRendererFactoryを介して登録する。 |
installDefaultRenderer | Backgroundの描画を行うRendererを登録する。 |
オペレーション | 説明 |
---|---|
render | 実際に描画を実行する。 |
Rendererに対して与えるValueオブジェクトとしてframeworkにおいて、RenderEventが定義されている。 上述の設計変更により、Rendererの探索をRendererLocatorに変更した。 また、RenderStrategyにセットされているBackgroundカラーも渡すように変更した。
属性 | アクセス | 説明 |
---|---|---|
mLocator | private | 指定された状態に対応するRendererを探索するオブジェクト。 |
mGraphics | private | 描画先。 |
mBackColor | private | Backgroundカラー。 |
mBounds | private | 描画領域。 |
mState | private | 描画したい状態。 |
フィルオミノでは、描画全般の管理クラスとして、FilloRenderStrategy、
Rendererと状態とのマップを管理するクラスとして、FilloRenderLocatorを定義した。
これらのコンポーネントの静的な構造とRendererに対して送信するValueオブジェクト、は下図のようになった。
図:画面の表示のクラス図
実際に描画を実行するRendererの実装はRendererFactoryを介して作成、登録する。
オペレーション | アクセス | 説明 |
---|---|---|
install | public | Rendererを構築し、RendererLocatorに登録する。 |
バックグラウンドを描画するRendererはRendererFactoryを実装した 抽象クラス, AbstractDefaultRendererFactoryを介して作成、登録する。 このFactoryは、デフォルトの登録処理が実装されており、 このメソッドの内部でRendererを作成するcreateRendererを呼び出す。 クライアントコードでは、createRendererをオーバーライドする必要がある。
オペレーション | アクセス | 説明 |
---|---|---|
createRenderer | protected | Rendererを構築する。 |
フィルオミノでは、これらのクラスを実装した、
FilloStateRendererFactoryとFilloDefaultRendererFactoryを定義した。
RendererFactoryを取り巻くクラス間のRelationshipは、下図のようになった。
図:RendererFactoryのクラス図
マウスアクションやキー入力を統括させるため、FilloInputHandlerを定義した。 問題をロードした後、アクティブポジションを(0, 0)に動かす必要があるが、ProblemLoaderからは動かすことができないため、 インターフェースInputHandlerを下表のように定義た。FilloInputHandlerはInputHandlerも実装している。
オペレーション | アクセス | 説明 |
---|---|---|
initActivePos | public | アクティブポジションを初期化する。 |
また、FilloInputHandlerの静的構造を下図に示した。 黄色く色づけられたインターフェースは標準ライブラリに含まれるものを示している。
図:FilloInputHandlerのクラス図
以上のコンポーネントをJava AWT/Swingと連結するコンポーネントは下図のように定義した。
図:Java AWT/Swingとの連結部のクラス図
以上の詳細化により、各オブジェクトの動的側面は、分析オブジェクトから下図のように修正された。
図:Rendererの登録のシーケンス図
図:表示の更新のシーケンス図
図:単一区画の選択のシーケンス図
図:数字の入力のシーケンス図
図:問題のロードのシーケンス図
prev : [システム分析] up : [目次] next : [テストケース]