Abstractions live longer than details
We come across Abstractions every day. The computers, phones or any electronic item we use or any machine that we come across abstracts out a lot of things from us including our own body.
It is a major concept in programming too. The right abstraction makes any system simpler, and thus keeps our codebases simple too. We use frameworks and/or libraries to help us abstract a lot of things for us.
The pragmatic programmer book talks about a lot about the importance of abstraction, the layered design, decoupling, and orthogonality. Let us look at a few principles mentioned in the book related to abstraction.
There are no final decisions
One trap all of us fell into is assuming that the decisions made now are final and cast in stone. This assumption makes any system rigid. For eg: for our product, we integrated with bit.ly for URL shortening. We had a few SMSs that goes out of the system which used the URL Shortening service.
And one day bit.ly was down and it affected our system. Even after few minutes, the service didn’t come up. As the SMS was very critical for us, we moved to Google URL shortener and deployed again. As this integration was abstracted out, it was possible for us to do this quickly and deploy and bring our services back.
While working with another product we had to move from Redis to H2 database because of some reasons and we could do that in few days and deploy and migrate the existing data. This was because of the right abstraction that we had created. We were not using any ORM frameworks but had made sure that we have the right abstractions and followed a layered design.
Put Abstractions in Code, Details in Metadata
The question is what to abstract? Pragmatic Programmer talks about that too. Andy Hunt and Dave Thomas has explained that in detail in this interview. Some excerpts from the interview:
Andy Hunt: Abstractions live longer than details. Details are volatile. Because details are going to change, put the details where changing them will create the least amount of friction. Typically that’s outside the code base — in a database, a properties file, or XML — something acting as metadata. We suggest an overall architecture where you put your energy into creating the right abstractions in the code. And as much as possible, push the details out somewhere else where they are easier to change, because that is what’s going to change.
Dave Thomas: When people read our advice in the book about metadata , they tend to imagine very complicated architectures with lots of abstraction. But in reality, it could be very simple. If the sales tax rate is currently 7%, I don’t put 7% into the code. I put it into a properties file or the database. The sales tax rate is a detail I abstract out of the code and store externally. Once you’re comfortable with pulling out simple metadata, like a sales tax rate, you can go further. You can start asking yourself, “What are the actual chunks of code that I’m processing to handle this particular order of business?”
And about the question how will you know what will change, is a matter of experience and at times it is common sense. Quoting Andy Hunt’s here:
Andy Hunt: I think knowing what to make configurable is largely a matter of experience. Some of it is just common sense, but most of it is experience. In a couple of instances I have decided off the top of my head to stick a parameter into a properties file, to help make the system soft and flexible. But when I talked to the user, I learned that the parameter hadn’t changed in 30 years. A parameter like that isn’t likely to change in the future, so it probably belongs in the code.
But as Sandi Metz recommends, prefer duplication over the wrong abstraction. What is more important is to keep things simple and if an abstraction makes things more complicated, it’s a wrong abstraction and duplication might be the better there.
Few people had written to me mentioning that they learned the concept of Branch by Abstraction from the posts Long living branches — An Anti Pattern, Continuous Delivery for Database. This made me think about the concept of abstraction.
Start with abstracting out details and push it further for orthogonality to bring in decoupling. This brings in enough simplicity to the codebase and allows to change any part of the system without having to break the entire system. As Paul Hammant mentions, allowing to change the wheel of a car while it is running.
Abstractions beyond code
The concept of abstraction is not restricted to the codebase. It is applicable wherever communication is important. The right abstraction improves the communication. In my earlier post Requirements Pit, I spoke about the importance of documenting requirements with the right abstraction.