I have a question about the "single responsibity principle".
I'm a hobby-gamedev. I try to organize code into different systems, but I often end up with a few classes that know a lot about other classes, and I'd like to know if there is a way to avoid this.
As an example: Let's say, I work on a citybuilder (like Cities:Skylines, but really crappy) and I want the player to be able to build roads in the game. To build a road a lot of different systems have to be used, for example:
- InputHandling: handling of mouse input (clicks, movements) to start and end roads and determine the position and shape of the road
- MeshBuilder: generate and constantly update a mesh for the road (or a mesh for a colored "proxy road" to visualize whether the road can be build)
- Geometry/CollisionHandler: to find closest roads/junctions for "snapping" and to check whether the new road collides with existing geometry
- RoadNetwork (a directed graph of all roads and junctions, used for pathfinding and more): to determine whether the road can be build (there may be some "logical" restrictions, e.g. only a limited number of roads can connect to a junction)
- Scene: to add/update the new Mesh/Model
- UI: to give feedback to the user in case of errors (in the sense of "You can't build here.")
- and more
I have no problems to separate all that functionality into the mentioned systems or helpers. But then there is a level "above" all that where I usually end up with classes (here a "RoadBuilderTool") that use all these systems to implement the "stuff that actually needs to happen" = the logic of building a road, and those classes depend on all the lower-level classes.
"Separation of concerns", "Single responsibity principle" and similar guidelines tell me that I should avoid that, but I don't see how to do it here.
Perhaps Events/Messages could be used to avoid coupling here, but I think Events also hide the flow of the execution and that's not great.
This is just one example of many. I manage to organize and separate code into different systems, until I don't, and I'm not sure what would be a better way to do this (or even if there is a better way).
Thanks for advice!