Let’s imagine a perfect programming world. In this world, everyone would always agree on everything. There would be only one language, one API, and one paradigm. No one would ever question this methodology, since it would work perfectly, and would be capable of doing everything imaginable. Language flame wars would disappear. The Right Way To Do Things would be obvious. In short, it would be pretty awesome.
Of course, our imperfect programming world doesn’t work that way, and never will. People have different opinions, and thus we have different ways of doing things, which manifests itself in different languages and paradigms. With so many different opinions, things can get complicated. One of the more popular opinions on how things should be done is Object Oriented Programming, or OOP.
For my latest project (which I mentioned here), I wanted to do things the OOP Way. Because, as we all know, OOP is awesome. How can it not be? Java, which is obviously the best language ever since it is so popular, forces you to do OOP by making you put all your code in classes. Every language on the planet, even functional ones like OCaml, has some sort of object system. So it must be pretty good.
I was pretty excited about learning the right way to do all this OO stuff. I had always struggled with it. When I first moved to C++ from C, I had a hard time integrating objects and classes into my code. Even when I started using them, it didn’t feel like I was using them enough. This project would be my chance to make a real OO application: everything would be in a class, interfaces would be public, data would be private… it all sounded so good.
So, I started coding. In my previous projects, I would usually just start writing the game loop. This would consist of the code to poll the keyboard and mouse, update the screen, and render everything. Pretty simple, but it was sufficient. But it was obvious to me now that that was a horribly un-OO way of doing things. I was going to have to start with the Input class, which would derive from the abstract base class GameComponent. It would have an override of the virtual update() method which would put the state of the keyboard into a public static vector. That sounded pretty OO to me.
The Renderer class would be in charge of drawing the screen, but I would first need to think about how the objects on the screen would be represented. I decided that when the game loads, I could append a MenuComponent to the Game class’s GameComponents list to represent the first menu the player sees. The Renderer could loop through the GameComponent list and use RTTI to see if the component it was looking at was a Menu, and then draw it accordingly.
There was actually much more to the code than what I’ve described. I was up to nearly 400 lines, and the only thing I had to show for it was a window with a black square. It was mostly OOP boilerplate code. 400 lines is incredibly tiny in the grand scheme of things, but for a project of the size I was working on, it was too much. The design was already beginning to break down and become hard to maintain. Various things in the C++ language were also starting to annoy me. I decided that it was time to do a complete rewrite; in Python.
Things are going smoothly now. 30 lines of Python has replaced my 400 lines of C++, and the code does more. I’m also back to my old way of programming, where I just write code that does things rather than worrying about OO design. I can attribute my increased productivity to one or more of a few factors:
- Object Obssessed Programming is stupid.
- OOP design is really hard, and I just had a cruddy design.
- Python is a far better and more productive language than C++.
The third one seems likely. A lot of the best programmers I know despise C++. The second one is probably true too. You can’t slap together OO code and have it be perfectly maintainable, and you can’t become an OO developer overnight. Designing large systems, and designing them well, takes practice. You can probably tell that I haven’t practiced too much.
The first one is the one that I’ve been thinking about lately, and I believe that it’s a true statement. Object Oriented Programming can be a good thing; Object Obsessed Programming cannot.
What’s Object Obsessed Programming, you ask? It’s when people go overboard on OO design; they stress out about getting it Just Right. Which is what I did. I started fussing about what should be public and private, who should inherit from who, and the like. I thought that by getting everything right, I would have a wonderfully written program. I ended up with a horrible one.
Smalltalk (the first OO language) was fairly simple. Member functions were public, variables were private, and classes could singly inherit from each other. Objects were useful data structures; they were there to help you, not hurt you.
Today, OO languages have added all sorts of weird features and terms: public, private, protected, virtual, abstract, the list goes on and on. In their quest to make all ideas enforceable, they severely limited programmer productivity. We have developers who are thinking about whether to have SingletonXMLParser inherit from SingletonTemplate or XMLObject, and they shouldn’t be. They should be writing code that gets things done.
Objects are useful, they really are. If you have an object like thing in your code, like a sprite in a game, make it an object. Give it an internal state, and some public functions for operating on that state. But it’s just silly to write entire programs based on objects. You’ll get lost in the details. That kind of OO design is really hard to get right, and if you get it wrong, you’ll have headaches down the road, or you’ll have to do a complete rewrite. A poorly designed OO program is harder to maintain than a million lines of Basic with GOTO all over the place.
I’m not really sure where I’m going with all this. I thought I was going to expose some sort of grand truth, that I was going to keep people from making the mistakes I did. Instead, I talked about what I’ve done with my project so far, followed by a rant about OOP. Take from it what you will; I guess I was just trying to warn you not to go overboard on OOP. But I’m sure someone much smarter than me figured that out a long time ago.