Small reference to one of my favourite authors, Tad Williams, in the title of this post. But the quote, taken from the Memory, Sorrow and Thorn series, really paints the picture I wanted for this post in terms of the lesson I found myself suddenly learning yesterday. I don’t know how useful an article this will be, but I guess I just wanted to write out my thoughts because they seem important to me. Guess that’s why they call it blogging, huh?
The system I’m building is a kind of a specialized content management system for my company’s website. As such, each “page” can define its own “template,” or layout system that defines the specific view. My boss was very impressed by this system, which is good, but later he called me with another idea: why not create two folders for templates, one for templates that are reusable, and one for templates that pretty much only get used for a specific page and never again.
On the surface, this seems to make some sense: we do have one-off pages that would require a template that never gets used again. But for reasons I couldn’t quite articulate at the time, I thought it was a terrible idea and still do. After a night to think it over, I realized that the challenge in programming is always the edge case and that the goal is to eliminate them, not create them. Here’s what I mean:
Lets say for example that we want to create two “buckets” of information, Category A and Category B. A specific set of conditions defines what qualifies for each bucket. We setup logic to compare a data set against this set of conditions and place it in the right bucket. Immediately, we have created a decision point. If the decision is simple and mathematical – size of a file, lets say – there are no edge cases. But if the decision is more complex or based on human decision making, there may be thousands of specific data sets that either fit into both or neither bucket. Then what?
Well, then we have to define a more stringent set of rules, don’t we? Or else more rules. Herein lies the problem, because you can drive yourself nuts trying to come up with a solution for every case. Worse than that, you can riddle your code with flaws and – as the title of this post suggests – create a set of rules so stringent that entirely separate parts of your code are immobilized for fear of violating those rules.
Such is the case with the current website, frankly. Its very well programmed, but unfortunately, so many rules and so many eventualities have been programmed for that its almost as if they’ve painted themselves into a corner. What was built to be flexible is now anything but.
Object Oriented Programming will not help this kind of thing. If the rules of one portion of the program obligate another part of the program overmuch, even cloud-based, OOP web services would grind to a halt.
So, what I’m getting at here is that any new decision point needs to be carefully considered in context. Does the decision represent a really necessary component of the system? Forget the perceived benefits of that decision point, what are the flaws or disadvantages that this decision point would eliminate? If there aren’t any, are the benefits really that valuable? Finally – and perhaps most critically – how many edge cases can you think of and is it really worth the brain power to figure out solutions for each one?
I think another bad habit of us programmers is that we are so enamored of our ability to solve problems programmatically that we feel the need to do so at every step. Here again is an opportunity to introduce new and mind-numbingly confusing edge cases where they’re not needed. Every web page does not need to be assembled by a foreach() loop, if/then decisions and switches: sometimes, plain old HTML with a few choice includes will do just fine.
Its an irony that, after really nearly thirty years of off-and-on programming in everything from BASIC2.0 to CakePHP, I’m only just now appreciating in definable terms: the logical conditions that make programming possible and programs flexible can also be over used to the point of farce.