まだちゃんと分かってない。例のゲームシステム。
ここで試したゲームシステムですが、まだちゃんと理解していませんでした。
分からないところというのが、マネージャーを多段に噛ました場合のメッセージ転送方法です。
例えば次のような構成で作る場合、
GameManager implements IStageManagerCtx ┗ StageManager implements IPlayerCtx, IEnemyCtx・・・ ┣ Player ┣ Enemy ・ ・ ・
PlayerがGameManagerのデータを参照したい場合、どうすれば良いか。
この場合、StageManagerがGameManagerの情報をPlayerへ橋渡しする必要があると思うのですが、
それをしようとすると路頭に迷ってしまいました。
まずはStageManagerがGameManagerからデータを取得する場合、
IStageManagerCtxにGameManagerからデータを取得する処理を定義、GameManagerで実装します。
これは前回書いた通り。
で、IPlayerCtxにStageManagerがGameManagerからデータを取得する処理を定義、StageManagerで実装・・・
とやってみたら、GameManagerからデータを取得できませんでした。
GameManagerはStageManager::execメソッドを呼ぶ際、自身を引数に指定します。
StageManager::execメソッドの引数は、context:IStageManagerCtxなわけで、
IStageManagerCtxで定義された処理を呼び出し、GameManagerからデータを取得できると。
このcontextからデータを取得する処理をIPlayerCtxに定義して、
IPlayerCtx::execメソッドを実行すれば、GameManagerのデータを取得できるはず・・・と思っていたのですが。
contextはexecの引数なので、exec以外のメソッドからはアクセスできません・・・。
なので、GameManagerのデータの取得ができないです。
対策としてほんとにパッと思いつく方法としては、
StageManagerにcontext:IStageManagerCtxをメンバとして持たせます。
これならIPlayerCtxでcontextからデータを取得する処理を定義すれば良いだけです。
確かに「メッセージを転送する」という意味では転送になるんだろうと思いますが、
StageManagerがメンバにcontextを持つという設計は、あまり美しくないんじゃないかと。
もうひとつは、
class StageManager { private var _player:Player; public function exec(context:IStageManagerCtx):void { _player.exec(this, context); } }
というように、Player::execメソッドをStageManagerのthisと、context:IStageManagerCtxを2つとも指定する方法です。
これも転送・・・ですかね?
ただし、PlayerがGameManagerから取得するデータをStageManagerが制限できません。
いわばPlayerのGameManagerに対するアクセス権がStageManagerと同等になってしまい、
システムの意義がなくなるんじゃないかと思います。
このゲームシステムの各クラスがどういう役割で、何をすべきなのかをちゃんと分かっていないのかもしれません。
ここを決着をつけてから先に進みたいところです。