Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a good pattern for storing implementations of an interface and retrieving specific implementations?

I am writing a simulator that has several interfaces which all simulated objects implement. The Entity interface has methods that all objects must have, such as ID retrieval and advancing the time step for the object's state. Collidable extends Entity, and represents anything with volume and position that should be considered when collision detection algorithms run. Field extends Entity, and represents anything that maps a location to a value; these are used to model things like magnetic fields that permeate the world but have no volume or physical form. RigidBody is a class that implements Collidable and provides rigid-body dynamics algorithms. I have a World class which manages all Entities and has methods for advancing the simulator's clock and partitioning the world so as to make collision detection more efficient.

My issue involves retrieving Entity subtypes from World. Originally, World just had a map of Entities keyed by ID, and to retieve a Field or RigidBody there would be methods that would grab the Entity out of the map and do an instanceof check plus a cast to the desired subtype. I'm well-aware that instanceof usage is frowned upon, however, so I tried another approach.

Currently, I have separate maps within World for each interface. For instance, there is a map for Collidables as well as a map for all Entities. The addCollidable() method will add to both maps, and getCollidable() will retrieve only from the Collidable map. This avoids instanceof, but it still seems like poor design to me. If I dream up another interface to extend Entity, I'll need another map in World and corresponding methods.

I feel like this issue isn't terribly obscure, so what is typically done in this situation?

EDIT

I don't believe the Visitor pattern will work here, as Visitor allows you to dispatch on the concrete type, and some of my retrieval methods need to retrieve interface types. For instance, Visitor would work if World only needed methods to retrieve RigidBodies and other such concrete classes, but I cannot make a method that retrieves all Collidables with Visitor.

like image 437
derefed Avatar asked Apr 09 '12 04:04

derefed


2 Answers

Here what you can use is visitor pattern, This tutorial on Visitor Pattern use it against a similar issue you are having. http://www.youtube.com/watch?v=KSEyIXnknoY

like image 164
asela38 Avatar answered Nov 13 '22 15:11

asela38


Using instanceof is frowned upon because it often appears in contexts where it hints at incomplete encapsulation. For example, instanceof is sometimes used to distinguish between different kinds of objects and then operates on them depending on their type. A cleaner way of doing this could be to put the code into the corresponding classes of the objects and to use polymorphism instead. So, instead of never using instanceof, rather ask yourself whether your current use of instanceof might be legitimate?

In other words: Is it possible to move the code that depends on the type of the entity into the corresponding entity class? (Of course, once you reach a conclusion this should be documented, as things may change.)

BTW I think you can easily generalize you current design by using a Map<Class,List<Entity>>, which would allow you to keep entity lists for an arbitrary number of types. You could also have an array Class[] types = {...} that contains all types that need to be distinguished. Now you only need a single instanceof operator in a for loop within your add/removeEntity(...) methods, which would walk through all the types that need to be distinguished and adds/removes the entity to/from all relevant lists.

like image 32
Roland Ewald Avatar answered Nov 13 '22 15:11

Roland Ewald