Skeletons in the (Software Architecture) Closet
ITConversations recently published an OSCON 2005 session by David Heinemeier Hansson titled Secrets behind Ruby on Rails.
Even if you’re not a Ruby developer (which I’m not at the moment), this podcast episode is 16 minutes well-spent. In defending his position that “flexibility is overrated”, David makes the following comment:
“Too many technologists are chasing flexibility as thus it was free. It is not.”
Amen.
There’s no shortage of developers and architects who not only err on the side of configurability and/or future-proofing, but cut the wheel and swerve hard in that direction. My counter-arguments and counsel have traditionally drawn upon the Extreme Programming credo of YAGNI (You Aren’t Gonna Need It), and the Zen of Python, among other software writings to complement my first-person experiences. The rapid adoption and success of Rails provides additional points of reference that are well-grounded not just in theory, but in the heads-down, pragmatic implementations that moves our craft forward.
Even if you are not working on a Rails project, there are software architecture lessons to be learned from the successes and challenges that the Rails community faces as it moves through its adolescence.
I like to make the analogy that application architecture is much like a skeleton. It’s comprised of bones and joints. Bones are the well-defined elements of the application, the behaviors of the application that are well-understood, and therefore can be built rigid and strong. Joints are the points of flexion, accounting for uncertainty and/or future change either through dynamic behavior or external configuration.
IMO, the challenge of good software architecture lies in the proper layout of bones and joints in building the skeleton of your application.
If you have too much bone and too few joints, your architecture is unnaturally rigid, and making change involves literally breaking a bone and then coding your way through its repair.
Conversely, if you have too many joints and too few bones, your application will not have enough internal structure to stand on its own. Now your application probably needs to lean on an XML Configuration-based walker just to stand upright. It doesn’t get much less agile that that, metaphorically speaking.
The other issue that frequently arises is the misplacement of flexion points, making the application flexible in areas when far simpler solutions would suffice, and hardcoding specific behavior where flexibility is genuinely useful.
The classic example of misplaced flexibility is the case where an architect in a solid 100% Oracle (or 100% Microsoft) shop designs a complicated and opaque “data abstraction layer”, so that the application would require minimal changes in the event that the company nullifies long standing enterprise vendor relationships at some point in the future and forces the migration of all legacy applications built atop database vendor A to now run atop database vendor B, and the company chooses to not leverage such a seismic event to refactor, rewrite, or retire said application. In this example, the codebase is encumbered (and a chunk of the budget depleted) in the interest of building functionality that addresses a risk that is very, very unlikely to materialize.
If you’re that forward thinking, you might as well code your application to be flexible enough to address the Y10K Bug
By treating your application architecture as a skeleton, you will hopefully be able to put flexibility in your application where it makes sense, and reduce the risk that well-intentioned but misplaced flexibility becomes a skeleton in your application’s closet.
P.S. While some may consider the previous sentence to be a mixed metaphor, I disagree. Given the “Web 2.0″ world in which we’re living, I prefer to think of it as a Metaphor Mashup.