If I say I have a hierarchal entity framework, rather than a component model. Something like:
(Yes, this is made up)

Or, more of a classical example:

How far would you split up the source/header files for readability and organization? Is it best to go something like Entity.cpp, MovableEntity.cpp, Enemy.cpp, etc. or would an approach like Entity.cpp [containing Entity and MovableEntity] and Enemy.cpp [containing Enemy and WalkingEnemy] be better? (Or in a more language agnostic way, an Enemy file and an Entity file vs a file for each class?)
Also, would this affect anything other than readability and organization?

| improve this question | | | | |
  • 1
    \$\begingroup\$ Nitpicky, but I don't think language-agnostic is an appropriate tag since it depends greatly on the language you're using as to the side effects. \$\endgroup\$ – Tetrad Aug 9 '10 at 18:11
  • \$\begingroup\$ Good point, I think I can retag. \$\endgroup\$ – The Communist Duck Aug 9 '10 at 18:14

This is entirely a matter of preference. However, I personally believe it is best to err on the side of more files. Java requires one class per file, with the filename the same as the class name, for example; they do this by policy to enforce this good practice (though you can have subclasses which basically get around this).

Also, source control systems are pretty good at merging changes in a file, but it's less of a hassle if you're just working in totally separate files. You can also easier see who changed which class. Let's say another developer makes a change to the file AllEntities.h; you have no clue exactly what entity (or entities) he changed until you open the file and look at the diff output.

It's great to group small structs and enums related to class within one class's file, though. If you have an enum that's only used by a single class, why split it into its own file? Just put them together. But if it's used by another class (i.e. another class member is of this enum's type), that's when it is time to give it its own file.

| improve this answer | | | | |
  • \$\begingroup\$ Agreed. Complexity of your types should definitely be a factor. If your language supports partial classes (or if member implementations can be organized similarly to C++), then I would even recommend breaking up particularly complex types into multiple files. For example, if there's a (large) interface that your class must implement, but the code is fairly generic and not terribly relevant to the rest, you could break that code out into a separate file/partial class. For enum types, I think you could get away with placing all enums for a given namespace within a single file. \$\endgroup\$ – Mike Strobel Aug 9 '10 at 19:09
  • 1
    \$\begingroup\$ Doesn't grouping your enums mean changing a single value would cause a recompile of every file that uses an enum in that namespace? \$\endgroup\$ – The Communist Duck Aug 9 '10 at 21:00
  • \$\begingroup\$ Well, that really depends on the language, but yes, it could certainly have that effect. It's not really an issue for me, as I develop primarily in C# (no file-by-file compilation), but it could be problematic in C++ and other languages. As always, there are language-specific factors to consider, and that would be one of them :). \$\endgroup\$ – Mike Strobel Aug 9 '10 at 21:28

Many languages outside of C/C++ impose constraints on files. Ricket mentioned Java's 'one class per file'; Python uses files as namespaces; other languages often copy the spirit of those.

If you are using C or C++, more included files generally means longer compile times per file; on the other hand, fewer means more to recompile when making small changes. Because enumerations cannot be forward-declared in C, you should always put them into header files containing only other enums, for dependency sanity.

Otherwise, Java's "one file per class" is reasonable, but for a long time Java has supported inner classes - like a container, and an inner class of its iterator. Similarly in any other language you'll probably want one dominant record/struct/class/type/interface/blorb per header, but may decide to include related helpers or containers as well.

(You don't need to use a component model, but if you have a deep and specific class hierarchy like that, you are going to hate yourself later.)

| improve this answer | | | | |
  • \$\begingroup\$ I was using the hierarchy as an example; I felt it did emphasise what I meant better. In actual code, I'm striving towards components. \$\endgroup\$ – The Communist Duck Aug 9 '10 at 17:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.