In today’s post I’m sharing my newest experience, which I gained while trying to create something that started out as a tiny practice program and turned out to be a massive disaster (interested readers can download the source here), but let’s get to the beginning. The main reason for starting to write this program was to learn about the mouse and keyboard event handling of OpenCV, and as such the original code base was not bigger than a main function plus a couple of additional helper functions. Since there was no intent (originally) to grow the code beyond this, I thought there is no need for unit tests (although this would’ve been a great opportunity to practice writing them). This was mistake #1.
After this point, I thought it would be nice to add a couple of features, as that would allow me to test out even more OpenCV functionality within a single application. This was mistake #2. The mistake wasn’t in the need to add new functionality, but rather in the fact that it wasn’t planned from the beginning at all, and thus the story went down an inevitable path (in hindsight). Because there was no planning whatsoever, I simply started to add new functions when a new functionality was required, and of course, with the ever increasing complexity of the program, these functions started to require global variables for communication. After having accumulated quite a few of globals, some of the functions and all of the globals had to be transferred out to a separate class. But then the class became too big, and had to be split into two, then three, and so on. A class hierarchy was soon needed to somehow organize the classes and create some coherency in the program.
But the need for new functionality didn’t end here, as I decided to create an actual working application, more precisely a small paint application written purely on OpenCV basis (no toolkits) called oCVPaint (mistake #3). Again, the mistake wasn’t in trying to create the application, but (yet again) in the decision to radically change the intent of the program. Let’s remember that originally this was a program to test out event handling, which grew to a small toy program for testing additional OpenCV functionality, and now it tries to become a full blown application. Of course, I wasn’t planning it to be a usable program for the general public, but who knows what other ideas I could’ve gotten later on :) ?
Anyway, new intent usually requires new features to be added, so a simple class hierarchy wasn’t enough anymore, but the existing codebase had to be massaged into some sort of GUI library to meet the new requirements. Since the classes were created in a kind of ad-hoc manner (mistake #4), refactoring was a true pain. I couldn’t help but think that the codebase was a true example of spaghetti code, a mess that was especially hard to add new functionality to. To be able to facilitate the addition of a new feature, a ton of other code (compared to the size of the actual codebase) had to be reorganized every time. Before long, I realized that I was spending a whole lot more time on refactoring than on adding actual new code. As a matter of fact, there were cases when I was forced to spend entire evening programming sessions just to refactor the code to a state, where I could squeeze in something new.
Obviously, the final judgement was to abandon the project and learn from it, as productive time (from a learning and building perspective) was reduced to almost zero. So what are the things that I would do differently next time? I guess if I were to decide on growing a tiny learning project to something bigger, then I would restart the whole thing from scratch while thinking very carefully about the possibilities of future expansions. Also, I would write unit tests from the very beginning, as in addition to their obvious benefits, the writing of the tests themselves also kind of guide the design of the program (according to some people at least, see this book I reviewed earlier).
So was it worth the time? Absolutely. Would I do it the same way? No. But I guess that is the point and hopefully I will step into similar huge traps in the future as well, as I found this project to be extremely educational.
As always, thanks for reading.