9

すべてのシミュレートされたオブジェクトが実装するいくつかのインターフェイスを持つシミュレーターを作成しています。インターフェイスには、EntityID の取得やオブジェクトの状態のタイム ステップの進行など、すべてのオブジェクトに必要なメソッドがあります。CollidableextendsEntityであり、衝突検出アルゴリズムの実行時に考慮する必要があるボリュームと位置を持つものを表します。FieldextendsEntityであり、場所を値にマップするものすべてを表します。これらは、世界に浸透しているが、体積や物理的形状を持たない磁場などをモデル化するために使用されます。剛体ダイナミクス アルゴリズムRigidBodyを実装および提供するクラスです。Collidableすべてを管理するWorldクラスがありますEntitiesまた、衝突検出をより効率的にするために、シミュレーターのクロックを進め、世界を分割する方法があります。

Entity私の問題には、からサブタイプを取得することが含まれWorldます。元々、ID によってキー付けされWorldた のマップがあり、マップから取得して、チェックと目的のサブタイプへのキャストを行うメソッドが存在します。ただし、使用法が嫌われていることは十分承知しているので、別のアプローチを試みました。EntitiesFieldRigidBodyEntityinstanceofinstanceof

World現在、インターフェイスごとに個別のマップがあります。たとえばCollidables、 のマップとすべてのマップがありますEntities。このaddCollidable()メソッドは両方のマップに追加し、マップgetCollidable()からのみ取得しCollidableます。これは を回避しますinstanceofが、それでも私には設計が不十分なようです。を拡張するための別のインターフェイスを思いついた場合はEntity、別の map inWorldと対応するメソッドが必要になります。

この問題はそれほど曖昧ではないように感じますが、この状況では通常何が行われますか?

編集

Visitor パターンがここで機能するとは思えません。Visitor を使用すると具体的な型をディスパッチでき、私の取得メソッドのいくつかはインターフェイスの型を取得する必要があるからです。たとえば、Visitor は、取得するメソッドやその他の具象クラスがWorld必要な場合のみ機能しますが、 Visitor ですべてを取得するメソッドを作成することはできません。RigidBodiesCollidables

4

3 に答える 3

1

ここで使用できるのは訪問者パターンです。訪問者パターンに関するこのチュートリアルでは、発生している同様の問題に対して使用します。 http://www.youtube.com/watch?v=KSEyIXnknoY

于 2012-04-09T05:08:42.143 に答える
1

不完全なカプセル化をほのめかす文脈でしばしば現れるため、使用instanceofは嫌われます。たとえば、はさまざまな種類のオブジェクトを区別するために使用されることがあり、その種類に応じてそれらを操作します。これを行うよりクリーンな方法は、コードをオブジェクトの対応するクラスに入れ、代わりにポリモーフィズムを使用することです。したがって、 をまったく使用しないのではなく、現在の?の使用が正当であるかどうかを自問してください。instanceofinstanceofinstanceof

つまり 、エンティティのタイプに依存するコードを対応するエンティティ クラスに移動することは可能ですか? (もちろん、結論に達したら、状況が変わる可能性があるため、これを文書化する必要があります。 )

ところで、を使用して現在の設計を簡単に一般化できると思いますMap<Class,List<Entity>>。これにより、任意の数のタイプのエンティティ リストを保持できます。Class[] types = {...}区別する必要があるすべてのタイプを含む配列を持つこともできます。これで、メソッド内のループで1 つのinstanceof演算子だけが必要になります。この演算子は、区別する必要があるすべての型を調べて、関連するすべてのリストにエンティティを追加/削除します。foradd/removeEntity(...)

于 2012-04-09T20:00:15.980 に答える
0

特殊な処理が必要なデータの特別なサブセットであるため、ワールドクラスの衝突可能性に追加のフィールドを使用することは、私にはもっともらしいようです。

ただし、私が変更する唯一のこと (主に個人的な好みによる) は、List<Collidable>タイプとして使用することです。これは、必要に応じて、衝突チェックのためにそれらすべてを反復処理するため、リストはより高速で軽量なアプローチであるためです。

于 2012-04-09T14:19:24.077 に答える