Globals couple you tightly to that implementation, and now for your code to run, it has to be there. If you want to reuse that component elsewhere, in another part of your game or in another game entirely, you also have to recreate the global. Additionally, it’s not always obvious that the code in question depends on that global… especially if you use a lot of different ones. When you use dependency injection, it’s generally much more clear where your data is coming from, local to the object using it.
This is a great question! Inheritance can definitely lead you down the wrong path. It’s extremely useful if you want to have common code between multiple objects, but it definitely should be used with caution. A more flexible approach is to prefer composition… build your object out of several different dependencies. In the case you suggest, where you want an enemy that is both fast and big, pass in behaviours that control an enemy, or manipulate its data in the ways that you want. Now you want an enemy that can fly? Pass in another behaviour that adds flying.
For the most part, I absolutely agree! Programming, at it’s core, is a creative process. There is freedom in how things are assembled and, at the end of the day, the most important thing is that it functions correctly. It’s important to take a look at all of the different styles people use and think critically about them. What advantages do they bring, what disadvantages? How will they impact your project?
On the other hand, and please keep in mind that I’m not talking about you specifically here, programmers are fundamentally lazy. I’ve seen way too many developers reject these newer practices and methodologies because they don’t know them, or they’re not what they’re used to. It’s not easy to change your approach to software development and time and again I see people resist good design practices because of the additional time and effort it takes to either learn, or to implement. I’m not innocent of this either… the first time someone came to me and said, “Hey, SOLID principles are going to generate far more stable and maintainable code, we’re going to use them now.” I was like, “But why? My code works great!” Here’s the big secret… my code was full of maintenance issues and once I got really honest with myself, I just didn’t want to effectively relearn how to code.
It’s a fine line to walk. There’s sooooo many different approaches out there that it can be overwhelming to consider them all, but it’s also extremely easy to fall into a trap of putting the blinders on and thinking you don’t need need to change anything because “that’s how we’ve always done it!”