はじめに
前回の続きです.今回はアーキテクチャの設計意図を残せればなと思ってまとめます.
図がビミョーな感じもしますが,次に向けて改善もしてく予定なので優しいコメント待ってます.
アーキテクチャ全体設計
トシキングのアーキテクチャ全体をパッケージ図で示すとこうなります。
それぞれの責務として
パッケージ | 責務 |
---|---|
Ev3StateMnager | 走行体の3状態:ゲーム前・ゲーム中・ゲーム終了を管理する |
GameStateManager | コンテスト内の3競技:走行競技・ブロックビンゴ競技・ガレージ競技を管理する |
BehaviorModel | 競技を攻略するのに必要な動作モデルを定義してGameStateManagerから指定できるようにする |
DeterminationModel | 競技を攻略するのに必要な判定モデルを定義してGameStateManagerから指定できるようにする |
Ev3DeviceDriver | ev3apiを使用して,センサやモータからのI/Oを処理する |
となりました.
次に詳細設計と分け方の意図を一緒に説明していきます.
アーキテクチャ詳細設計
図全体を載せたら文字かつぶれて見えなくなってしまったのでシステムへの要求パッケージとEV3への要求パッケージに分けます1
まずEv3StateMnager・GameStateManager
パッケージは,システムへの要求を実現するために作っています.なので,例えばコンテストの機体がEV3から他のものに変わってもEv3StateManagerを変更すれば他への影響は出にくいと考えています。また,GameStateManager
も同様に競技の内容が変わったとしても,新たにTemplateGameState
を継承して作ればうまく機能すると考えています.ただし,実装をしているうちに動作と判別モデルをまとめたRunSectionParam
構造体については,GameStateManager
にいるのはふさわしくないため,別途新しいパッケージが必要です.
振る舞いとしては,下の図のようにRunSectionParam
の配列を定義し空なら次の競技状態に遷移します.
次に,BehaviorModel・DeterminationModel・Ev3DeviceDriver
パッケージでは,EV3への要求を実現するために作っています.BehaviorModel・DeterminationModel
においては,システムからの要求単位がRunSectionParam
構造体の単位なので,各モデルにRunSectionParam
を引数としたInterface
クラスを導入しました.これにより,Template
から個々にモデルを作ることができ,かつ各モデルのテストも簡単に行うことができます.改善点としては,Ev3DeviceDriver
にセンサとモータのI/O処理を押し込めたため,両モデルで使用されているWheelDeviceDriver
が肥大化しているところです.また,新しいモデルを追加する際に,
- enum型のBehavior/DeterminationListに動作・判定を定義
- Templateを継承してモデルを定義
- Interfaceの条件に追加
と工程が多いため,この手間をなくせるような設計が作れたらなと思っています.
実装はGitHubに上がってます.
さいごに
UMLでクラス図を設計しながらコードを書いて実装していると理想の設計と現実の実装で阿鼻叫喚することが多いのでおすすめです.
まだまだ,UMLモデリングとプログラミングを紐づけて開発するのは難しいですが,案外楽しいのでこれからも続けていこうかと
個人的には,実装で詰まったときは大体設計のせいで,設計で詰まったときは大体アルゴリズムを理解できてないときだとこの頃感じてます.
あと多重度は慣れてないから許して・・・
ちなみに何度も繰り返して学んでいくのは計算論的思考らしいので,UMLモデリングとプログラミングの中から見つけていきたいなぁ
-
Qiitaさんベクタ画像対応してなかった・・・ ↩