C#
C#

help

Root Question Message

lukkasz323
lukkasz3231/25/2023
✅ Help me understand what a "God" class is and why/how should I avoid it.

I'm specifically referencing to this: https://en.wikipedia.org/wiki/God_object

The first example is how my current game project is structured. The second is a different example that is my other theory how a "God" class might look like.

Which of these are God classes? Both? Neither?

Why is this even considered a problem?

How an alternative could look like?
flkXI
flkXI1/25/2023
from reading the description
flkXI
flkXI1/25/2023
you basically need to put the code in the class it belongs
flkXI
flkXI1/25/2023
not make a code noodle soup
lukkasz323
lukkasz3231/25/2023
What about the " all-knowing object" description?

The "Game" class has access to every part of the program through it's members.
flkXI
flkXI1/25/2023
well it's just an object that references others
flkXI
flkXI1/25/2023
nothing special really
flkXI
flkXI1/25/2023
if you need to access the objects you can ask the god class I guess
ChucklesTheBeard
ChucklesTheBeard1/25/2023
1st, it's a very, very good idea to learn about this.
2nd: in game design, performance is god and many good enterprise design practices are sacrificed at the altar of performance, possibly including "never use god objects".

A "god class" is a class that knows too much; it knows that Processors need to update Entities, but some Entities have to talk to a Processor and check for collisions with non-entity objects in this Scene but not that Scene, and that UpdateSystem needs to run part 1 before part 2 and EntityManager can only have 4 objects at a time because... WHOA WHOA WHOA, this is supposed to be a high-level class, we are way too deep into the weeds, there are too many levels of abstraction are mixed together... this class is trying to do everything. If you want to add a new Entity you may need to update 40 lines of code scattered throughout the god class to make it work.

A SOLID class is only responsible for exactly one thing; if you want to add an Entity, you define the new behaviors in one 40 line chunk, then update maybe one or two lines in directly adjacent classes, to call the new behavior.
ChucklesTheBeard
ChucklesTheBeard1/25/2023
Of the two example diagrams, the 2nd is much more likely to be a god class than the 1st
lukkasz323
lukkasz3231/25/2023
Now that I think about it, I made every member in my composition public, only now I see how much nested access it has.
lukkasz323
lukkasz3231/25/2023
I think only tried to limit child -> parent access, but not the other way around.
lukkasz323
lukkasz3231/25/2023
and didn't even succeed at that lol
ChucklesTheBeard
ChucklesTheBeard1/25/2023
child -> parent and parent -> child can be ok... the problem becomes more obvious when you have parent->child->grandchild->greatgrandchild->...
lukkasz323
lukkasz3231/25/2023
I see
ChucklesTheBeard
ChucklesTheBeard1/25/2023
if greatgrandchild needs a change, you don't want to have to modify all 3 other classes
lukkasz323
lukkasz3231/25/2023
I feel like I get confused sometimes with names when talking about composition of objects. Are you refering to inheritance here?
ChucklesTheBeard
ChucklesTheBeard1/25/2023
Layers of abstraction
ChucklesTheBeard
ChucklesTheBeard1/25/2023
Program (yep, I'm running it on a computer) -> Game (needs to know how to be a game) -> Scene (particular collection of behaviors; here's how the update loop runs in the "pause menu" scene or whatever) -> EntityManager -> Entities (perhaps including the "save & quit" button)... Program should never ever need to know the damnedest thing about a save and quit button, frankly neither should Game or probably even Scene
lukkasz323
lukkasz3231/25/2023
I understand. What do you think about a situation when the "save & quit" button has access to other intermediate objects like for example Entity creator, or a list of sound files that can be played?
ChucklesTheBeard
ChucklesTheBeard1/25/2023
Those requirements should be gathered elsewhere and handed to the button, the button itself shouldn't know the details of how they were assembled.
class SaveAndQuitButton : Entity
{
    var _listOfSoundFiles;
    public SaveAndQuitButton(List<SoundFiles> injected){
        _listOfSoundFiles = injected;
    }
}
, not

class SaveAndQuitButton : Entity
{
    var _listOfSoundFiles;
    public SaveAndQuitButton(TightlyCoupledParent p){
        _listOfSoundFiles = p.SoundFilesListCreator.Create();
    }
}
lukkasz323
lukkasz3231/25/2023
I see, thanks, that's very helpful.
ChucklesTheBeard
ChucklesTheBeard1/25/2023
This is called dependency injection, there are other approaches that operate on the same principle (like, passing in a kinda godlike "dependancy manager" object) but that's the simplest I think
Scratch
Scratch1/25/2023
In terms of responsibility, each class should have a single responsibility. A god class has many. A common thing I see new game devs make is a "GameManager" class that just does everything
FusedQyou
FusedQyou1/25/2023
There's nothing wrong with a God class
lukkasz323
lukkasz3231/25/2023
I feel like "single responsibility" is very poorly defined. One could say that "Managing the game" is the responsibility of the "GameManager" class and there are no other things the class must do, so therefore it follows that principle.
FusedQyou
FusedQyou1/25/2023
People just decide to throw unnecessary shit in a God class
FusedQyou
FusedQyou1/25/2023
It's perfectly reasonable to create a God class if it's an entrypoint to the main behaviour of something. Like with a game, being able to start/stop it or adjust certain rules without going into the dependencies that hold the main logic for them
FusedQyou
FusedQyou1/25/2023
A God class is also a very good place to apply main communication between dependencies that rely on eachother, without making them communicate directly. This is a very good way to scale
FusedQyou
FusedQyou1/25/2023
I made a console for Unity yesterday doing exactly this and it's very easy to use, adjust and read in general
lukkasz323
lukkasz3231/25/2023
And that person would be right from a logical standpoint. I'd be surprised If I was the only one that doesn't really understand the scope of this principle.
dont
dont1/25/2023
if you have a class called SomethingManager that's quite a yellow flag to begin with
lukkasz323
lukkasz3231/25/2023
So you mean that there should be no classes that manage other things?
dont
dont1/25/2023
exactly, it shouldn't "manage", it should do something specific
if it's called Manager then you have no idea what it really should do
it has... all the responsibilities? which goes against previous said principle
lukkasz323
lukkasz3231/25/2023
I see, this makes more sense
Scratch
Scratch1/25/2023
I read Clean Code. Uncle Bob says that functions should be operating at a single "level of abstraction". A "manager" can be fine if the way it's interacting with other objects is at a very high level. But if it starts getting deep into messing with other objects it'll quickly become a mess and way too many responsilbilities.
ContactFrequently Asked QuestionsJoin The DiscordBugs & Feature RequestsTerms & Privacy