Why I Beat Up Your Cat Object
For a few months I was wondering what was going on -- why I couldn't get back to work, programming again on my huge web app project that I eventually plan to release on GPL and then form a business around it. (This will be my second startup.) I was more prone to watch a movie or play my guitar than to write software. Yet writing software is important to me because it is a huge release for my creativity, because I have faith in my abilities, and because I've had some financial troubles recently that make writing software and getting another startup company off the ground that much more important.
I hate to say it, but it dawned on me. I didn't use enough OOP. I hate OOP, really. I use it sparingly, but I definitely do use it. I just don't like sitting in long meetings discussing the nuances of OOP models and UML. I loathe it. Instead, I use OOP to build classes much like one builds a function library in C. I don't bother with inheritance, polymorphism, things like that. Been there, done that; it slowed me down and added little to value or speed. It rarely helped the teams I worked on. For me, it's all about abstraction, which also goes by the names of "information hiding" and encapsulation. And you won't catch me building a cat object, or a dog object. Instead, I build the cat's toolbox of methods for cattiness. Instead of a .ini or .xml or .conf settings file, which I find slow, I realize that PHP, my language of choice, is a scripting language, after all, and I write a class file full of properties that my web app can pull while it does its catty deeds. That way, at least the bytecode runs fast and one can almost use it like a .conf file.
But I digress -- why call a cat object, after all? First, you have to declare its variable, then instantiate it, then set its properties, then call its methods like walk, run, leap, etc. Look at all that work. Instead, I build a very small set of objects that split up the functionality of my web app. I have one called "page", for drawing gadget components on the page, and one called "db" for all things dealing with the database. I also have a $settings, $web, and $strings object, which should be obvious by now what they do. I have to instantiate this once on a page. Then, to draw a grid on the screen, I need only to call the page object and call the grid method, passing it a set of variables. Now some may argue, but if you use inheritance, you could make one grid object that did one thing, and another that inherited from this and did another thing. Yes, but I can also cut and paste that method and customize it just as well. I find, too often, that the energy wasted to make the supremo set of page gadgets that others can extend with inheritance -- that energy could be better spent elsewhere, getting real work done. So thank goodness for cut and paste. The infamous web essayist, Paul Graham, states
, "Object-oriented programming generates a lot of what looks like work."
So, enough of this. What was holding me up? It was the page class. I hadn't used one. When I first started the project, I was simply excited to get some momentum and I didn't have much need for a page class. I was writing PHP with server-side code at the top of the page and HTML at the bottom. At first I only had a few interleaving statements of PHP and loops in the HTML. It was no big deal. But then the ideas poured in. Since I have to moonlight this whole operation, and since that drags this project out, I started to see on the web all these cool things that my app could be doing too. I knew that mine had to include at least some of these concepts. And, as that started to happen, the project dragged on and on and the interleaving of HTML and PHP grew a bit like spaghetti. Still, at that point, I had invested so much time in the application, and it seemed at first to be near finished if I could just work in about 10 more features. Well, those few features caused a snarl of a mess. Tables lost their alignment. Fonts started switching on me in odd places. When the page was resized on a huge monitor, stuff went wacky and looked terrible. I also reflected upon the fact that I had not used enough CSS, that I still used the FONT tag, which is pretty much a no-no to zen worshipers of CSS, and, horror of horrors, I was using TABLEs to position elements on my page instead of DIVs, which is also a no-no these days.
I had to eat my pride. I had to say, well, time for a new project
. I moved the old source code to another directory, not destroying it, and relabeled it as "prototype". I then decided to do something I had never done before on this project -- write a functional specification with some typical use-cases inside. I wrote it in my favorite text editor with ASCII chars. -- nothing special. That exercise made me feel really good. It energized me. I had so much energy that I needed to purchase a voice recorder for my long commute so that I could talk about setting goals and what I would commit to as far as a project schedule.
Starting fresh, I knew that I still had a good deal of my old code base as valid code to reuse. I then agreed to NO MORE PHP/HTML INTERLEAVING! Instead, I would consider the entire GUI of the web app as a set of gadgets. A page class would be necessary, and 100% of all HTML would need to be included in that class. Starting fresh also allowed me to integrate in more CSS and use DIVs for mostly everything except tabular data such as rows from a database. For those, I would use TABLEs because DIVs don't do a great job, without a lot of effort, in creating columns and rows in such a way that everything stays aligned. I mean, I'm sure I could master it, but then that's wasted too much effort when an ordinary TABLE will do. So, I bent a little to the TABLE-less HTML crowd and am now about 95% DIVs.
It was a lot of effort at first to make this page class. I probably spent about 2.5 weeks building it. It has transformed my app into something that looks stunning on the screen to me, and, again, this is energizing me.
So, with the introduction of the page class, and the purity of this new project, and a smooth functional specification that draws from an almost-finished prototype that took me several years to build, I'm actually getting things done very rapidly now. I also use OOP the smart way, in my opinion, rather than, to quote South Park, assert my authoritaaaaaaay
and look like I'm actually getting something done when I am not.
And a sidenote. Some might ask why I don't just go ugly early and release this code as is. This is especially a GPL/GNU/FLOSS programmer trait. For me, however, I'm too selfish. I'm like an artist. The beta from me has to be so clean on the inside as well as the outside of the code, and so hip with sensible features, and yet still follow a Keep It Simple methodology, that I cannot release it until it's ready. And right now, it's like going into a garage and seeing a Ferrari laying in parts on the floor. The thing's a beauty when put together, but it's embarrassing when left on the floor. However, once the beta goes out, I will be amenable to customization and improvement. There will be no more Cathedral-style programming for it after it goes beta. It will be Bazaar-style programming from there on out.
But most of all, if I'm writing this, and you're reading it, then we're not getting back to work and we should be. I guess I cannot be all about coding and not about communing. I had to take a quick break. Good luck with your startup, too!