My favorite SOLID principle

Roman Weis
CodeX
Published in
3 min readJun 15, 2022
Photo by Ameer Basheer on Unsplash

Some years ago I was asked the following question in a technical interview: “What is your favorite SOLID principle?” I thought it was an odd question since all of those principles seemed equally important to me and formed SOLID. If you leave one out you won’t have SOLID anymore, but more like SOLD or OLD.

Fast forward a couple of years and I realize that there is in fact this one principle showing itself in different forms and on different occasions. Adhering to this principle helped me to create modular software systems with scalable data models and to write code which is easy to reason about. It is the principle that works beyond object oriented programming and embraces immutability as first class citizen. If you couldn’t guess it by now: I am talking about the Open/Closed Principle.

Open for extension, but closed for modification

There is a lot of programmer wisdom condensed in this short sentence. “Closed for modification” basically tells us to write code which is immutable once it’s released. Think about smart contracts on a blockchain as an extreme case where it is not possible to modify released code. There you cannot just rename a field or delete an existing one, the code is closed for modification. But you could possibly extend it by adding new smart contracts that work with existing ones and extend their functionality. If the trend towards decentralized peer-to-peer systems with smart contracts and permaweb storage continues, programmers will be forced to change their thinking about code.

But even today with our large enterprise software systems, embedded systems and mobile applications it’s advisable to write code with some foresight. We should be able to add new features to our code base without touching existing functionality. This will greatly reduce the risk of regression bugs and overall code complexity.

It’s easier to implement the Open/Closed Principle if we imagine our code as a set of independent DAGs (directed acyclic graphs). Every time when we add new functionality we add new nodes to a graph or create a new graph instead of changing old nodes. Of course we need to be pragmatic about changes and especially, if there is a bug, we will have to update existing code. But designing our code with additive changes in mind instead of modifications, our software system will become automatically more modular.

Creating good extension points is not easy. In my experience code that does too much or too little prevents us from extending the functionality. Obviously if the code does too much, it becomes difficult to use the code for other use cases where only a certain portion of the functionality is needed. We are forced to split the code up, add parameters and make other modifications. An alternative would be code duplication, and although it sounds wrong, in some cases it might be even the better option. On the other hand, if the code does too little, it becomes almost impossible to use it in a meaningful way. Although, we don’t modify the existing code, we do create a huge dependency graph with a single point of failure.

There are certainly points in time where existing code is no longer supporting the business case. But in the meantime, for any non-trivial project, it is beneficial to design our code in a way that doesn’t require a complete rewrite a couple of years down the road. Instead we should thrive to build high quality, immutable code which we can extend and build upon in the years to come.

--

--

Roman Weis
CodeX
Writer for

Software Engineer, SaaS Enterpreneur. Founder of https://www.stamy.io. Writing about Software Engineering and other brain teasers.