Evaluating Depth of OOP Class Hierarchy in Python for Game Development

game developmenthierarchyobject-orientedpython

So I am making a Super Mario Bros NES clone in pygame and for all enemies that are drawn to the window, I have a class hierarchy that is 5 classes deep. Going in the order of:

  1. Object (A base class for all things drawn on the screen)
  2. Character (A class for any type of character, playable or not)
  3. Enemy (A class for any enemy in the game)
  4. BasicEnemy (A class for any enemy that only moves horizontally, as they both act the same, just different visuals. This includes Goombas and Koopas).

Then the deepest classes are Goomba and Koopa, with the class structure stated above. I am doing it this way because all objects that are drawn to the screen all have common properties, as well as all characters, enemies and basic enemies. For example, all enemies move horizontally through the exact same method (adding their x velocity to their x position). I have read in many places that too much inheritance is bad. I'm not sure if what I am doing is too much. And if it is too much, how should I be doing it?

Best Answer

I would have your objects implement interfaces like ICharacter, IEnemy, IHorizontalMover. The relevant design guideline is known as Favor Composition over Inheritance, and it should allow your design to be more flexible. One difference is that interfaces tend to specify behavior and any given object can implement as much or as little as it needs.

If you feel that this causes code duplication that you did not have when a base class just handled mostly non-overridden methods, then you should be using forwarding methods, where your implementing classes forward method calls to a private class (or stateless static class) that provides a function common to several implementations. This keeps the codebase DRY (meaning Don't Repeat Yourself). It can feel like you are writing more boilerplate lines to achieve what inheritance takes care of for you behind the scenes, but it is generally considered worth the effort, leaving the codebase more flexible and open to change than a pure inheritance design.

Related Topic