The reusability fallacy - Part 1
Why the reusability promise does not work
The reusability fallacy – Part 1
After several posts discussing different aspects of IT as a whole, I would like to start discussing another thread of thinking: software architecture. This is a huge topic and I pondered for quite a while where to start. Finally, I decided to start with debunking the long-lived architectural myth of reusability because this makes it easier to understand some of the ideas that I will discuss in later posts.
The structure of this little blog series is:
- Why the typical reusability promise does not work (this post)
- The costs of reusability and reusability suitability of a solution
- Reusability in distributed systems
- When and when not to go for reusability (and what to do instead)
A recurring topic
Reusability is a recurring topic that I discuss for lots of years meanwhile:
- One of my first public talks discussed reusability 1.
- I wrote an article about reusability for a (German) IT journal at the same time.
- Some years later I published a post discussing reusability on the blog of codecentric AG.
- I discuss this topic in many of my talks and workshops, especially in the context of service design.
Yet, all these places only discuss selected aspects of the reusability fallacy. Here I try to brings those aspects together and discuss reusability in a more comprehensive way – probably still missing some relevant facets.
Reusability is sort of a holy grail in software architecture and design for many years. The discussion about reusable software modules 2 gained momentum in the early 1970s. E.g., the seminal computer science paper “Structured design” by Stevens, Myers and Constantine from 1974 already discussed reusability as one of the goals of structured design. 3
This discussion persists until today. And admittedly, the idea is intriguing: I create a software module once and as there are basically no reproduction costs in software, I can reuse it at no cost in as many places as I want. Invest once, harvest forever. What an efficiency lever! What a cost saver!
Hence, it is not surprising that generations of IT managers demand reusability as essential design goal, and their high priests, the architects in return try hard to deliver reusability. Over time this yearning for reusability has become independent. Nobody asks anymore if reusability makes sense in the given context. Reusability is important. Period!
Eventually, it even turned around: architects discovered that they can use reusability as a powerful sales argument for the introduction of new architectural paradigms. It was not necessary that they proved their claim. Simply arguing with reusability was enough to convince IT managers of the new paradigm. The typical reasoning was (and still is) as follows:
We definitely need to invest in implementing <shiny new paradigm>. I know this does not create any business value now, but it allows to create reusable <building blocks of paradigm>! This way, we will have to pay a lot less for future projects, they will be a lot faster and we will be a lot more flexible. The investment will pay for itself in no time!”
From all that I have seen in my IT career, it never worked this way – and I am very sure, it also never will work in the future.
A deeply industrial belief
The reason why it never works this way, has several facets. First of all, reusability is a deeply industrial belief. In the physical world, reusability is mostly interchangeable with standardization. Standardized parts support building the product at a lower price and can easily be reused in multiple products. On the other hand, any part that is designed with reusability in mind is a candidate for becoming a standardized part.
The key aspect of reusability/standardization in the physical world is that it helps to save costs over time. You need to spend the efforts to design the part only once. The production process needs to be designed and set up only once. The required tooling needs to be created and installed only once. Afterwards you can produce as many copies of the part as you like without having to repeat the design and setup investments.
This way, reusability helps satisfying the key success criterion of industrial markets: scale production in a cost-efficient way. A big part of the cost savings comes from the production of the parts, that you can produce lots of them without having to design and set up the production process and tooling over and over again.
If you additionally create the part in a way that it can be (re)used in different contexts, you can produce an even higher quantity which helps spreading the fixed costs for design and setup even further, i.e., the part becomes even cheaper (in terms of costs, not quality).
Thus, consistently aiming for reusability makes a lot of sense in the physical world where you create houses, bridges, furniture, electronic devices, etc. from reusable parts. But transferring this idea of cost savings via reusability to software development is riddled with several caveats.
Implementation is part of design, not production
The first persistent misunderstanding is that writing code can be compared to building a house or assembling a car. The idea is that software architecture and design work can be compared to designing a car or house and writing code is executing the plan, i.e., assembling the final product.
Unfortunately, this perception is completely wrong. The final product in software development is the executable program. We usually create it by compiling the source code 4. In other words: IT has the probably most efficient production process imaginable for more than 60 years meanwhile – so efficient, that we usually completely forget about it.
Today, this production process typically is a step in a CI/CD pipeline, but it does not change the fact that we build our products in an extremely efficient way without any human intervention.
Writing code on the other hand is completing the design. The product design is only completed after the last line of source code is written. Writing code is like adding the details of a car design, designing the details of the shape, the interior design, the power transmission and so on – everything that needs to be done before a car can be produced. Producing the actual product, the executable program from the code is negligible in terms of time, costs and effort.
Writing code is completing the design.
Building the product from the completed design is just issuing a command (and has nothing to do with writing code).
Thus, all those metaphors that compare writing code with assembling a car or building a house are wrong.
This also means that the assumption derived from the physical world breaks that we can save lots of money in the production process by using reusable parts. The production process in IT is already unbelievable cheap compared to any physical domain. Additionally, we can produce as many copies of a part at basically zero cost: it is called the copy command.
Accordingly, all considerations that are based on the value of reusability in the physical world do not work in IT as reusability in software development does not help to save money in the production process.
The inherent lack of standardization in IT
This still leaves room for efficiency gains through reusability in the design process. To (mis)use the metaphor of automobiles once more: Many car manufacturers use a platform strategy these days, i.e., they reuse a lot of standardized base parts in their car designs. E.g., they do not design the engines or chassis from scratch for every new model they design, but reuse engines or chassis from their platform, complementing them with parts individually designed for the specific model.
While this platform approach of reusing parts again primarily targets cost savings on the production side (which is not relevant in IT, as we have seen in the last section), it probably also helps to reduce time, costs and effort in the design process.
We can apply this idea to software development: The more reusable parts we can use in our design, i.e., software development process, the more time, costs and effort we can probably save.
This is where another peculiarity of IT strikes.
In his famous essay “No silver bullet” 5, Fred Brooks reasons about essential and accidental complexity in software development. One of the drivers of essential complexity he lists is “complexity”:
Complexity. Software entities are more complex for their size than perhaps any other human construct, because no two parts are alike (at least above the statement level). If they are, we make the two similar parts into one, a subroutine, open or closed. In this respect software systems differ profoundly from computers, buildings, or automobiles, where repeated elements abound. […] Likewise, a scaling-up of a software entity is not merely a repetition of the same elements in larger size; it is necessarily an increase in the number of different elements.
First of all, Brooks clearly rejects the idea that we can design a software solution from a set of higher-level standardized building blocks in the same way as we can design a wall by arranging the same type of brick multiple times. Each part we use will be different from all other parts.
Yet, while making the case against standardized building blocks, Brooks still leaves room for reuse: he states each part in our solution will be different, but we may use a part several times from higher-level contexts. Following this idea, we reuse lower-level functionalities to support higher-level functionalities.
What is left for reusability
In this post, I tried to deconstruct a part of the reusability fallacy: the fallacy that we can save lots of money from a more efficient production process by using standardized, reusable parts. Software development is all about design. The design is only completed after the last line of code is written.
The actual production process, i.e., creating the executable program, is so efficient and cheap that there is nothing left to save. Thus, all the reusability approaches that take concepts from the physical world and try to apply them to software development do not work.
We are left with efficiency gains in the design process itself due to the use of reusable parts. In the next part of this little series I will discuss the costs of reusability, what we already have in place and why the initiatives to introduce new architectural paradigms that I mentioned before never pay for themselves.
But as this post is long enough already, I will leave it here for today.
The talk including the slides was in German. I only switched to English several years later. That is why I did not upload this deck (and several other old decks) to my public slide deck collection. ↩︎
I use the term “module” here. Over the years, the reusability discussion spread across all types of software building blocks that support the concept of modularization, e.g., functions, classes, components, services, and many more. Still, the underlying concepts are encapsulation and modularization. ↩︎
If you are an Academia member, you can try this link to access the paper. It is also included in the book “Classics in software engineering” from 1979, edited by Edward Yourdon, that you can still buy second-hand. ↩︎
I know that it usually takes a bit more than just the compile step to create the executable program and that not all programming languages get compiled. But for the point I want to make here, the simplified description is good enough. ↩︎
In case you do not want to download the paper from ResearchGate: if you search for the paper in the Internet, you will find various download options. It is also included in the essay collection The Mythical Man-Month: Essays on Software Engineering, Anniversary Edition (2nd Edition) by Fred Brooks which is still available. ↩︎
Share this post