Simplicity Before Generality, Use Before Reuse

[article]
Summary:
A common problem in component frameworks, class libraries, foundation services, and other infrastructure code is that many are designed to be general purpose without reference to concrete applications. This leads to a dizzying array of options and possibilities that are often unused, misused, or just not useful. Most developers work on specific systems: the quest for unbounded generality rarely serves them well (if at all). The best route to generality is through understanding known, specific examples and focusing on their essence to find an essential common solution.
A common problem in component frameworks, class libraries, foundation services, and other infrastructure code is that many are designed to be general purpose without reference to concrete applications. This leads to a dizzying array of options and possibilities that are often unused, misused, or just not useful. Most developers work on specific systems: the quest for unbounded generality rarely serves them well (if at all). The best route to generality is through understanding known, specific examples and focusing on their essence to find an essential common solution. Simplicity through experience rather than generality through guesswork.


Favoring simplicity before generality acts as a tiebreaker between otherwise equally viable design alternatives. When there are two possible solutions, favor the one that is simpler and based on concrete need rather than the more intricate one that boasts of generality. Of course, it is entirely possible (and more than a little likely) that the simpler solution will turn out to be the more general one in practice. And if that doesn't turn out to be the case, it will be easier to change the simpler solution to what you now know you need than to change the 'general' one that turns out not to be quite general enough in the right way.


Although well meant, many things that are designed just to be general purpose often end up satisfying no purpose. Software components should, first and foremost, be designed for use and to fulfill that use well. Effective generality comes from understanding, and understanding leads to simplification. Generalization can allow us to reduce a problem to something more essential, resulting in an approach that embodies regularity across known examples, a regularity that is crisp, concise, and well grounded. However, too often generalization becomes a work item in itself, pulling in the opposite direction, adding to the complexity rather than reducing it. The pursuit of speculative generality often leads to solutions that are not anchored in the reality of actual development. They are based on assumptions that later turn out to be wrong, offer choices that later turn out not to be useful, and accumulate baggage that becomes difficult or impossible to remove, thereby adding to the accidental complexity developers and future architects must face.


Although many architects value generality, it should not be unconditional. People do not on the whole pay for (or need) generality: they tend to have a specific situation, and it is a solution to that specific situation that has value. We can find generality and flexibility in trying to deliver specific solutions, but if we weigh anchor and forget the specifics too soon, we end up adrift in a sea of nebulous possibilities, a world of tricky configuration options, overburdened (not just overloaded) parameter lists, long-winded interfaces, and not-quite-right abstractions. In pursuit of arbitrary flexibility you can often lose valuable properties-accidental or intended-of alternative, simpler designs.



This article appears in 97 Things Every Software Architect Should Know. It is licensed under a Creative Commons Attribution 3.

User Comments

2 comments
Anonymous's picture
Anonymous

Interesting article. How would you apply this opinion to organizations that are deciding whether to purchase software off the shelf or build it in house?

February 23, 2010 - 2:33am
Joey McAllister's picture

Evaluate the options. Is the off-the-shelf software a good fit for an organization? Or does it come with a high 'reuse' tax? Namely, the cost of learning and the cost of adaptation, both of the software to the organization and of the organization to the software. Would developing the software in house be a cheaper option more likely to result in the right thing? Or is too complex, too costly or likely to end up in an overrun project? Evaluate by trying out both options to a limited extent: a proper usage-based evaluation of off-the-shelf software and initial prototyping of an in-house project.

February 23, 2010 - 8:52am

About the author

AgileConnection is a TechWell community.

Through conferences, training, consulting, and online resources, TechWell helps you develop and deliver great software every day.