Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python structural issue: Giving an 'engine' class to everything

I am having some issues making 'bigger than simple scripts and stuff' applications in Python. I have a class called WinMain, a class called Engine, one called State and another called Element. It's laid out like this:

WinMain is the main class of the program, it has a mainLoop function and various other things.

Engine is an object that contains data like images and rendering code.

State is an object held by Engine that has its update method called each time Engine's step function is called.

Elements are objects held by State that are things like gui buttons and pictures to render.

Since my rendering functions are in Engine, how will I get my Elements (held by state) to render things? I suppose I could give each Element the instance of Engine, but that seems to be kind of hacky, because I'd have to do stuff like this: picture = Element(engine, (0, 0), 'gui_image') (not good)

I'd rather do picture = Element((0, 0), 'gui_image') and still some how let the Element render things using Engine.

This seems to be a major structural problem I have with most projects I start, and I can't seem to find a way around it (other than passing a honkload of variables through the arguments of classes and functions). How might I do this?

like image 918
Name McChange Avatar asked May 11 '26 05:05

Name McChange


1 Answers

Engine is an object that contains data like images and rendering code

This sounds like a God class: they're common in GUI code, and the problem you're having is a common effect of that.

What is the conceptual relationship between different stuff in Engine? Does it need to be tightly coupled, or could the Engine just coordinate between the State, a Renderer and some other stuff?

However that bit breaks down, passing the Engine (or Renderer, or whatever) down through the state machine is the only way to avoid a global (or singleton) with your current architecture.


The usual way to break this dependency is to use something like an MVC (Model/View/Controller) pattern. Specifically, it sounds like the Engine is already roughly a Controller, and the State and Elements have the Model part covered. However, the Engine, State and Elements are also handling the rendering/presentation part: this introduces the coupling.

If you can find a way to publish the State changes to some observer (deliberately leaving that vague, because we don't want the State logic to depend too much on the details of the observer), you can make a Renderer listen to State (model) updates and draw them. Now, the observer can be anything you want, so it's easy to mock, and it's also decoupled from the Engine.

like image 187
Useless Avatar answered May 13 '26 18:05

Useless