The Mythical Man Month by Frederick P. Brooks has had an incredible impact on the software industry. In my last post I explored a few of my favorite takeaways from Brooks on estimating software development. This time around I’ll explore a few more lessons in building software.
The Second System Effect
When it’s time to update software and rollout a second version there’s a good chance things will go awry. As Brooks says: “This second is the most dangerous system a man ever designs…The general tendency is to over-design the second system using all the ideas and frills that were cautiously sidetracked on the first one.”
Takeaway: Exercise restraint the second time around in any domain and with any technology. Always keep a laser focus on what addresses real business needs and what truly adds value.
No Silver Bullet
“No Silver Bullet” was actually an essay published separately from the original book. I can summarize the basic point of the article using a few quotes:
“All software construction involves essential tasks, the fashioning of the complex conceptual structures that compose the abstract software entity, and accidental tasks, the representation of these abstract entities in programming languages and the mapping of these onto machine languages within the space and speed constraints.”
Or to put it another way:
“Following Aristotle, I divide [the difficulties of software technology] into essence — the difficulties inherent in the nature of the software — and accidents — those difficulties that today attend its production but that are not inherent.”
“The essence of a software entity is a construct of interlocking concepts: data sets, relationships among data items, algorithms, and invocation of functions.”
In other words, the essence is the problem you are trying to solve. The accidents are the complexities of languages, hardware, etc. Today we have the flexibility to solve the same problem using any number of technologies, which have their own accidental complexities. With that in mind, Brooks makes his assertion:
“I believe the hard part of building software to be the specification, design, and testing of this conceptual construct, not the labor of representing it and testing the fidelity of the representation…If this is true, building software will always be hard. There is inherently no silver bullet.”
I suppose that translates into job security for us software folks. And as a software developer, I love this little nugget of truth:
“Software entities are more complex for their size than perhaps any other human construct, because no two parts are alike.”
When two pieces of code are the same, we consolidate them. By nature, what is left over is unique code, everywhere.
So, what do we do with all that? Is software hopelessly complicated?
“The most radical possible solution for constructing software is not to construct it at all.”
Reuse. This is the only way to really address essential complexity. Reusing a pre-existing solution doesn’t make the problem easier or less complicated, but it does shrink the problem in the sense that part of the problem is already solved. This assumes, of course, that the accidental complexity of integrating with the pre-existing solution is less than the gains you make toward essential complexity.
Takeaway: My takeaways here are two fold:
When presented with a problem, first ask if the problem has already been solved in a way that can be leveraged given your project constraints. If not, only then should you start thinking about building a solution.
When evaluating technologies, platforms, or methodologies, keep your eye out for things that attack essential complexity, not accidental complexity. It is these things that truly deserve attention. For instance, new languages or frameworks that promise more concise code are interesting, but I’d rather focus on things that literally shrink the problems at hand.
“I will contend that conceptual integrity is the most important consideration in system design. It is better to have a system omit certain anomalous features and improvements, but to reflect one set of design ideas, than to have one that contains many good but independent and uncoordinated ideas.”
“Conceptual integrity in turn dictates that the design must proceed from one mind, or from a very small number of agreeing resonant minds”.
So ideally, the architecture and implementation of every solution should come from one mind. However, most of the solutions we create these days are far more complicated than one person can understand, so how do we address this? As Brooks points out, an effective way to do this for larger scale projects is “careful division of labor between architecture and implementation”.
Takeaway: Essentially, have one person or a small number of people design the architecture, focusing on interfaces between components. They define the “what” and leave the “how” up to the implementers.
If you have any questions please feel free to use the comments section below or contact us at firstname.lastname@example.org. Be sure to follow us on Twitter at @CrederaOpen or connect with us on LinkedIn to stay up to date with the latest Credera blog posts.