Is it better to have more Java classes, or have fewer classes doing more work? [closed]

StackOverflow https://stackoverflow.com/questions/15917696

  •  03-04-2022
  •  | 
  •  

Question

I'm currently working on a game. At the moment, I have one class (the game's environment) responsible for holding collections of game objects (enemies, weapons, etc.) and doing collision-checks, calling the objects' creation routines, etc. As I've progressed with the project, I've started to wonder if I should have a more layered approach - is it better to have, say, a WeaponsManager, an EnemiesManager, and an Environment holding everything together, or to have my Environment class manipulating each object as I'm doing right now?

It might be worth mentioning that the game objects are already fairly heavily layered:

BaseClass
-----EnemyClass
----------Enemy1Subclass
----------Enemy2Subclass
-----WeaponClass
----------Weapon1Subclass
----------Weapon2Subclass

BaseClass has basic object properties defined, such as position. EnemyClass and WeaponClass are fairly generic classes that define more class-specific methods and properties, such as speed for EnemyClass or damage for WeaponClass. They mostly exist so I can have fairly generic collections instead of a separate collection for each individual enemy/weapon type. Enemy1Subclass/Enemy2Subclass and Weapon1Subclass/Weapon2Subclass are the actual enemy/weapon classes, which are actually created and used.

My Environment class stores collections of EnemyClass/WeaponClass and does the necessary manipulation by calling the game objects' methods.

Environment (manipulates EnemyClass and WeaponClass objects by iterating over their respective arrays and calling their respective methods; doesn't do any subclass-specific stuff)
-----EnemyClass array
----------Enemy1Subclass entry
----------Enemy2Subclass entry
----------Enemy1Subclass entry
-----WeaponClass array
----------Weapon1Subclass entry
----------Weapon2Subclass entry
----------Weapon2Subclass entry

But now I'm wondering if yet another layer of separation would be a good idea, with Environment holding EnemyManager/WeaponManager classes and the respective managers holding and manipulating their collections:

Environment (calls generic instantiation, destruction, moving, etc. methods in EnemyManager and WeaponManager; doesn't ever directly interact with an EnemyClass or WeaponClass object)
-----EnemyManager (gets instructions from Environment and manipulates EnemyClass objects to carry out those instructions)
----------EnemyClass array
---------------Enemy1Subclass entry
---------------Enemy2Subclass entry
---------------Enemy1Subclass entry
-----WeaponManager (gets instructions from Environment and manipulates WeaponClass objects to carry out those instructions)
----------WeaponClass array
---------------Weapon1Subclass entry
---------------Weapon2Subclass entry
---------------Weapon2Subclass entry

Thoughts? Suggestions? I've not been able to find anything about this kind of "more classes or harder-working classes" convention, so any answer is fair game, right up to and including "your model is trash, start over." Although hopefully it won't come to that. ;)

Was it helpful?

Solution

Generally speaking (very generally), a major advantage of object-oriented languages is Encapsulation - the idea that it is better to group related functions/methods and data together (with appropriate permissions). Applied here, that means that it is nicer to separate code as far as "it makes sense". In your example, "harder working classes" implies classes that are larger, more difficult to understand as a whole, and dealing with large amounts of data. Two nice guidelines that cover either side of the continuum:

  • If you need a flowchart to keep track of everything that happens inside one class, you should probably make another class
  • If you notice Class A only contains Class B which only contains Method C, perhaps this can all be within one function

    In summary, just do your best to ensure that your code is divided up in reasonable, NOT superfluous sections.

OTHER TIPS

Remember, in (almost) all programming, clarity is key.

In this case, do what makes the most intuitive sense. What I've found is that it's generally worth the pain to split programs and functions into multiple classes, because it improves maintainability, and makes code generally more explicit.

However, there is a fine line between syntactic sugar and syntactic saccharin. In other words, keep your organization as neat as possible, but don't overdo it. Do what makes your code the clearest.

In this case, this seems like a good use for interfaces. Try to avoid instanceof when you can create a new instance of an interface or abstract class.

Although it's good to think a bit about architecture before you start hacking - think of programming as an iterative process. So start with the simplest possible thing and then keep refactoring constantly. That way you don't overengeneer and keep your code maintainable. So concerning your post title, start with one class doing the work and if you come to a point where it makes sense to extract certain things, then do it - today's IDEs will make it very easy for you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top