So I recently learned about the importance of low coupling and high cohesion.
For those of you who don’t know what this means (You might understand the concept but don’t know the terms. Therefore, you may still be able to help):
Coupling has to deal with how much one class needs its other classes. High coupling would have classes needing each other and calling methods from each other often. This is bad. Low coupling would have each class only concerned with itself which, of course, is good.
Cohesion deals with the jobs of a class. High cohesion, which is good, is when each class has one job. Low cohesion is when you have one class do a ton of different things.
Unfortunately, knowing this and doing this are two different things. I am having trouble with this. For example, I have a camera. This camera knows the players location so that it can follow this. There’s coupling. Is that bad? How should I handle that? Then I have a recoil class. the camera has to know how much recoil is happening in order for it to take effect. Is that bad? Maybe it’s okay to access variables just don’t call methods… That just occurred to me. As long as the camera isn’t modifying these things it can’t be bad.
Now here’s my new question: what sets these? How does the camera know where to get these variables? I can’t hardcode the player and recoil classes in there. Then it would probably be bad coupling to have the player set them. How does the camera know where to get these variables without having bad coupling?
Now for a cohesion question (sorry this is going on forever). Say I want to make a level controller. So this class handles the level. What does that entail? Pausing and spawning and ending the level and reloading a checkpoint… WAIT! I just said and four times. That seems like low cohesion to me. I could put these things in separate classes, sure, but then this class still has to trigger the events, meaning it has to know about the other classes, meaning high coupling. And, overall, the level controller really is handling all these jobs. It’s just passing them on. It all comes back to the controller and I still can’t describe it well in one sentence without using and.
I really need help here. I seem to sacrifice cohesion for coupling or vise versa. How can I have both?
Thank you soo much for reading all this. I really really appreciate any help you can give me. I will never be a good programmer unless I get this right. So please post a helpful reply and I’ll be forever grateful.
PS: Sorry for the long post. I had a lot of questions. This is the trouble with self-teaching. I suppose that’s what these forums are for.
It depends I have a lot of classes that do one particular job, but then I have a few classes that uses these other classes to acheive something bigger.
For example, in an RPG game I am making I have a lot of monsters. Each monster consists of some components that help the monster do a particular thing. For example My monster objects have:
Eyes - this component checks to see if the player can be seen (The “player” is just a game object public property of the eyes, so the monster could in theory be set to check to see if it can see a tree).
Damageable Component - This component just handles taking damage from other game objects. It fires events when damage is taken or the monster dies
Weapon component - This component handles firing projectiles and provides methods to do this.
Damage display component - This component handles displaying damage (a health bar above the monsters head) this automatically searches for the above Damageable component.
As you can see these are very specific components. Eyes that allow a monster to know that he can see the player, damageable component to allow the monster to take damage and “die”, a weapon component that can create projectiles when called and a damage display component which automatically listens to events raised by the damageable component and displays the damage.
Now on the monster I have an AI script. This class is much bigger and is what achieves the actual intelligence of the monster by using the simple components. For example it checks the eyes component and when the player can be seen it will attack the player. It also uses the weapon component to actually initiate the attack. Finally if it takes a lot of damage (which it finds out by listening to the damageable component) it will initiate a run away action.
This is a simple description (I am using interfaces to provide multiple kind of weapons and monsters that have a 360 degree field of view or can only see at night for example). But I hope it shows how you can have a mix of simple scripts that are controlled by bigger classes. Kind of like how a car consists of an engine, doors, body etc.
Each of my scripts provide a set of properties that need to be set, either in the editor or via the AI script. Things like - the eyes location on the monster, where the gun should create projectiles from and what game object represents the player.
Doing this allows you to build a variety of easy to reuse scripts, and almost build new game objects like lego.
Stop spinning your wheels and over-thinking about problems you don’t have yet and just start building your game.
That being said - the Inspector is there; use it. You talk about some piece of functionality needing to know about THE camera. This doesn’t have to be true - it needs to know about A camera. So give it a Camera type member and set the value in the Inspector. You could then, theoretically/philosophically, re-use that code with any camera.
I’m going to approach this from outside the context of Unity.
The Cohesion/Coupling question is one of balance. The lowest possible coupling ends up with either one class for everything, or completely non-functional software. Same for high cohesion.
So, what’s the proper balance between these two concepts? Should I favor low coupling at the cost of lowering my cohesion? Should I favor high cohesion at the cost of raising my coupling? And this, unfortunately, is where you get the answer you don’t want to hear: There is no right answer. It’s a style decision.
The balancing of cohesion and coupling is the art of software development. How do you paint? Or write a novel? You find examples of what you like and copy what you see. After a while, your tastes will refine and you’ll start to develop a style of your own, and you’ll begin seeing examples of works where you can pick and choose bits and pieces that fit your style while rejecting those that don’t. That’s how all creative endeavors work, and software development is no different.
Read other people’s code. See how others do it and start copying those ideas. You’ll soon develop your own ideas about what the right balance is.
KelsoMRK’s remark is also appropriate. These are fine discussions to have, but don’t let questions of coding style cause you to miss deadlines. This is game development, not enterprise software development. In the enterprise, people you’ve never met will need to dig into your code in 5 years to add a new feature, so extending the development timeline to accommodate “proper” architectural decisions makes sense. That’s not going to happen with your game. Prioritize delivering a functional and bug free product over the more “enterprise-y” stuff.