The grand unified theory of the universe is a search for elegance. Mastering the art of winning a combinatorial game is a search for elegance. Discovering the attitude and philosophy of everyday living is a search for elegance. Good software design is a search for elegance. In the last 10 years of doing software design, the part I’ve come to enjoy most is achieving that palpable state of elegance. I can feel an elegant design soon as it emerges and what feels elegant at outset, tends to withstand the deep logical scrutiny that invariably follows. Elegance scales. Elegance embraces newness; newness that wasn’t considered or even known at the time of original contemplation. That, in fact, turns out to be the only objective test for elegance: how well it embraces and adapts to additions in specifications, to new information.
If you design a system over the long-term (years), incrementally adapt it to growing needs, there comes a time when the elegance breaks down. To retain the semblance of balance you expend tremendous amounts of energy, rethink everything, restructure, rewrite, redesign just to meet new requirements in a consistent manner.
However, another piece of information challenges this new design and you give in and accept the unweidlyness of evolution, the kludgeness of forms plastered onto an elegant system, turning it into a complexity that, while powerful, is aesthetically unpleasant. The system works, but it leaves you on shaky ground, specially with respect to the future.
There are umpteen accessible examples of this in the process of “designing” theoretical frameworks of natural phenomena. Physicists, biologists, chemists and geologists have tried, time and again, to fit new observations to existing theories, by proposing extensions that explain new observations in the framework of the existing theory. Apollonius_of_Perga’s epicycles are probably the most famous example. In order to accommodate troubling observations of varying planetary brightness and retrograde motion into the geocentric model of the solar system, Apollonius came up with idea of epicycles: planets did not circle earth in their concentric orbits, rather they were attached to circles (epicycles) within the concentric orbit. This model held for a while, but fell to further observations. Ptolemy, then, proposed the idea of epicycles within epicycles to “solve” for new observational data. Eventually, it all came tumbling down when Copernicus’s observation of the star Aldebaran could not be solved with any permutations of the epicycle equipped geocentric model. Copernicus proposed the heliocentric model and Kepler refined it to remove epicycles altogether. Elegance reigned once again.
Much like models (designs) from Aristotle (complex elegance) to Ptolemy (inelegant complexity) to Kepler (complex elegance), software design goes through the cycle as new requirements surface. We’ve all witnessed our beautiful software turn into a dangerous concoction, and then resolve into a higher level of elegance that continues to scale effortlessly (for a while).
The basic problem is that of a limited granularity of perception. We design for the requirements (or capture reality in an elegant model) based on the understanding of the world as it stands today. We use our predictive faculties to adapt our designs and models to what might appear tomorrow. But we can only see so far in the future. The universe is larger than our brains. This implies, any process of modeling or design will inevitably go through the cycle of “complex elegance to inelegant complexity” and, hopefully, back. If we formalize this notion, we can learn to discern when it occurs and modify our design processes to accommodate it. For instance one strategy that emerges from this knowledge is that if a new requirement doesn’t fit our design, we should not waste effort trying to fit it in the current model, we should just special case it and integrate the special case into an elegant whole when new requirements show way to a higher level of elegance. As Brook’s pointed out in Mythical Man-Month, “Plan to throw one away, because you will anyway”. Another strategy is to accumulate multiple requirements before hitting the design board, as multiple requirements are more likely to expose holes in the current design and hint at a better one.
Not all designs are elegant. If new requirements break a design, it is not necessarily an honest mistake. There are multiple ways to skin a cat, and it’s quite possible that you happened to pick the wrong one. How is one to know if a design is the best possible representation of the requirements? One way to examine a design is to see how tightly it is coupled to the requirements. The tighter the coupling, the poorer the design. If the design was created only to solve the particular requirements, it is more likely that it will break when new requirements arise. A design that is based on abstraction of the requirements tends to be more robust. In fact, the designers goal should be to abstract as much as possible from the requirements, and then design to the final abstractions. Is there a danger of being too abstract? Yes and no. This danger can be thought of as a trade-off with the time of implementation. A more abstract design will require the implementer to first create the abstraction framework and then specialize it to meet specific requirements. The advantage of an abstract design is that it leaves “space” to elegantly fit future requirements. It’s time expended upfront, but saved in future. We usually make this trade-off based on the importance, longevity, and other constraints.
Another way to assess the elegance of design is when it is replaced with a newer design. If major elements of of the original design were carried over into the subsequent one, than the original design could be thought of as elegant. The percentage of design elements borrowed is a good barometer of elegance. In case of the Solar System models, the element that was carried over from Aristotle’s model to Kepler’s was the idea of bodies circling each other in a concentric fashion. The only two mistakes was the choice of the body and shape of orbits. From that sense, Aristotle’s design was quite elegant. When Relativity and QM replaced Newtonian Mechanics it continued to hold true, it just became a special case of the overall picture. This, in my mind, is the best case scenario. If a design is retained as is, as a special case of the newer level of complex elegance, I believe the original to be a perfectly elegant solution for the time and circumstances of its creation.