SOFTWARE is a compound word made of SOFT + WARE and dictionary meaning of SOFT is;
easy to mold, not hard or firm, something that is easy to change
Before the software, we had machines or hardware. When there was a need for a machine to change its behavior, we needed to make some changes to its hardware too. Maybe add some components or remove some. Why we have to change & that too so often?
Well who could answer better than Darwin & Heraclitus ;
“It is not the strongest of the species that survives, nor the most intelligent that survives. It is the one that is most adaptable to change” — Charles Darwin
“Change is only constant” —Heraclitus
The very existence of the software itself is because we needed a way to change easily the behavior the machines work. –Uncle Bob
If we have to choose between there’s a software that works perfectly but difficult to change versus we have software that just works (not yet great) but we can make changes to adapt, which one would you choose? Few might say prior is better while others might argue over later. So which one is it?
‘Build to Last‘ might have been the popular mantra, but ‘Build to Adapt’ could be a way to go
We don’t need software that just works, but be able to build to adapt and most importantly build and adapt as quickly as possible. That’s easier said than done. Numerous challenges slow us down in achieving the state of adaptability. “What slows us down?” Well, it’s the crappy, unreadable, tightly coupled code that we have written or writing.
“You want to go fast, you do a good job,” Uncle Bob says. “Rushing will never make you faster rather it guarantees that you will be slow” he adds.
Let’s think of a situation, God forbid it won’t happen. If you are being operated for open-heart surgery and surgeon is working on your heart where he has a deadline too. And your soul happens to watch this whole thing. How would you like your surgeon to work on? Fast or Slow. Or would you like him to work like a typical software engineer?
I am sure you want him to do a good job with care, passion, and professionalism.
Can we bring a similar approach to building software? Can we figure out what is bad code?
Uncle Bob has beautifully explained “What are the symptoms of bad software?” in his video using rigidity, fragility & non-reusable code
Rigidity – High Coupling
Rigid code is the code that has dependencies that snake out in so many directions that you cannot make an isolated change without changing everything else around it. — Uncle Bob
If you often find yourself touching many modules of your project, whenever you make changes in a single class, it might mean a symptom of rigid code.
Fragile code breaks in bizarre and strange ways that you cannot predict. — Uncle Bob
Fragile code is a lot worse than the rigid code. Rigid code at least gives you an error or indication of what other parts of our code is breaking. While fragile code breaks in while it’s running.
In many cases, it’s the end-user who finds out that some feature isn’t working while in reality, you haven’t made any changes in that area at all.
As a software engineer often, we come across the phrase “Don’t reinvent the wheel”. Reuse! Reuse! Reuse!
However, it’s ironic that when we want to use some piece of code from other parts of the system or completely different systems, we end up getting some additional code that is not required. The reason is that the code we need depends on some other code that we do not need. in other words;
“You wanted a banana but you got a gorilla holding the banana.”
“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” ― Martin Fowler, “Refactoring: Improving the Design of Existing Code”
“Indeed, the ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write a new code. …[Therefore,] making it easy to read makes it easier to write.”
― Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship
While working on enterprise or legacy applications. I am sure it’s not an assumption, quite often it’s the case. We have to re-read the code multiple times, we have to jump around multiple files to understand what’s going on to make the desired change. It clearly means that the code is highly coupled and it was not designed to extend. As a result, we end up with a large portion of our time in reading/understanding than writing.
On the other hand, while working on startups. We have a clean slate. We can do what we like. In the early stages, things are not very clear or organized and we end up constantly adding new features, weekly/daily releases, etc. Structuring the code takes the back seat. We end up making excuses for time, client, organization, etc. Knowingly or unknowingly we end up building complex and coupled services/applications. In a couple of years, we enter the maintenance phase of the code. At this stage, we want to add a feature or enhance it. We face the same situation, we are re-reading our own code or jumping around to just to understand why I wrote that piece of code two years ago. Isn’t it quite frustration to read our own code to understand what it’s doing?
Irrespective of clean slate or enterprise applications we have the same set problems if we don’t think of designing for change.
“There are three constants in life…change, choice and principles.”Stephen Covey
You can achieve desired change , if you align your choices with the timeless principles that produce success. For a software craftsman to achieve desired adaptability we have S.O.L.I.D. principles amongst few other.
S.O.L.I.D is an acronym that represents five principles of object-oriented programming and code design theorized by our beloved Uncle Bob (Robert C. Martin) by the year 2000. The author Michael Feathers was responsible for creating the acronym:
[S]ingle Responsibility Principle
[L]iskov Substitution Principle
[I]nterface Segregation Principle
[D]ependency Inversion Principle
Please refer my upcoming post that are dedicated to each principle.