私は現在、すべて GameEntity クラスから継承する多数のエンティティ (GunBattery、Squadron、EnemyShip、EnemyFighter など) がある Scala でゲームを開発しています。ゲーム エンティティは、イベント/メッセージ システムを介して、関心のあるものをゲームの世界にブロードキャストし、相互にブロードキャストします。多くの EventMesssages (EntityDied、FireAtPosition、HullBreach) があります。
現在、各エンティティには、receive(msg:EventMessage)
応答するメッセージ タイプごとに固有の受信メソッド (例: receive(msg:EntityDiedMessage)
) があります。一般的なreceive(msg:EventMessage)
メソッドは、メッセージの種類に基づいて適切な受信メソッドを呼び出す単なる switch ステートメントです。
ゲームは開発中のため、エンティティとメッセージ (およびどのエンティティがどのメッセージに応答するか) のリストは流動的です。理想的には、ゲーム エンティティが新しいメッセージ タイプを受信できるようにしたい場合は、応答のロジックをコーディングできるようにしたいだけで、それを行うのではなく、他の場所で match ステートメントを更新する必要があります。
私が持っていた 1 つの考えは、Game エンティティ階層から receive メソッドを取り出して、def receive(e:EnemyShip,m:ExplosionMessage)
および defのような一連の関数を持たせることでしたが、これは、メッセージとゲーム エンティティ タイプreceive(e:SpaceStation,m:ExplosionMessage)
の両方をカバーするための match ステートメントが必要になるため、問題を悪化させます。
これは、 DoubleおよびMultipleディスパッチの概念と、おそらく Visitor パターンに関連しているように見えますが、頭を悩ませているところがあります。OOP ソリューション自体を探しているわけではありませんが、可能であればリフレクションを避けたいと考えています。
編集
さらに調査を行って、私が探しているのは Clojure のようなものだと思いますdefmulti
。
次のようなことができます:
(defmulti receive :entity :msgType)
(defmethod receive :fighter :explosion [] "fighter handling explosion message")
(defmethod receive :player-ship :hullbreach [] "player ship handling hull breach")