javaoopdrawablesfmlprogram-flow

OOP design: How to decide program flow and class responsible for method (JSFML library)


I'm designing a 2D game to practice Java and Object Oriented Programming (I'm using the JSFML library, if that helps), and I have doubts regarding how to best design the following:

The library I'm using offers a Drawable interface implemented by visible game elements (the player, enemies, backgrounds, etc). I also have a RenderWindow upon which I'll draw the Drawable objects.

Here's the thing, the RenderWindow has a draw(Drawable d) method that draws a Drawable object on the current Window, and the Drawable objects have a draw(RenderWindow r) method that draws the current Drawable object on the RenderWindow passed.

If they do basically the same thing, which one should I use? Why? What should I take into consideration to decide? I use a HashMap to store the Drawable objects. Should I pass the RenderWindow to the Drawables in the HashMap or pass the Drawables in the HashMap to the RenderWindow? Any advice is appreciated.


Solution

  • One line answer to your question would be
    Java language does not support double dispatch mechanism.

    What to do: The library expects you to override these methods but never call them. I haven't used the library but from some experience with game engines, I guess the application will call the RenderWindow's draw and it will eventually make calls to all Drawable's draw methods. (Collection of Drawables will be maintained by RenderWindow.

    Why: Java dynamically calls the method by checking the class of object on which the method being called (not by checking reference). This is called (as you probably know) dynamic dispatch.
    But the method's arguments are selected by only checking reference (not by class of actual object passed as argument.)
    Here, by forcing dynamic dispatch twice (by making two methods for same purpose), the library developers have indirectly implemented double dispatch.

    In future, you might want to extend both Drawable and RenderWindow. If you had draw method in only Drawable, you can't have separate draw for each child of RenderWindow. Double dispatch solves this problem.

    Hope this helps.