Keep your code open to possibilities

opinion
Feb 12, 20255 mins

The best software is built by keeping as many doors open for as long as possible. Resist premature decisions and locking in implementations too soon.

Illustration of man going own direction, trailblazing, exploring, thinking outside the box. Experimentation choice freedom concept.
Credit: fran_kie / Shutterstock

Iโ€™ve been developing software for many years now.ย Decades. Iโ€™ve learned a lot along the way, and I dare to think that Iโ€™ve collected some wisdom about software development worth sharing with others.ย At some point, you think โ€œYeah, Iโ€™ve got a grip on this thing.โ€

And every once in a while, you have some revelation that is the culmination of what youโ€™ve learned along the way.ย Iโ€™ll never forget the moment I understood dependency injection.ย Of course you would want to pass in an abstraction rather than create an implementation!

I had a similar revelation this week.ย Iโ€™m sure there are plenty of sager developers among you who have already figured this out, but it struck me suddenly that really good software design is all about keeping your options open for as long as possibleโ€”that you should defer any decisions to the very last minute.ย 

Now, this seems counter-intuitive. Weโ€™ve always been told to plan everything out ahead of time.ย That we shouldnโ€™t start the project without having thought about every detail that can be thought about. That we need to figure it out now so there are no surprises.

I can just imagine the conversation:

Engineering director: โ€œHowโ€™s the planning going on the new project?โ€ย 
Development lead: โ€œGreat, weโ€™re ready to get started.โ€ย 
Engineering director: โ€œWhat database did you pick?โ€ย 
Development lead: โ€œHavenโ€™t decided yet.โ€ย 
Engineering director: โ€œAuthentication?โ€ย 
Development lead: โ€œNot yet.โ€ย 
Engineering director: โ€œWaitโ€ฆ what?!โ€ย 

But the engineering director should be happy with those answers.

Hold out for abstractions

Making decisions early locks you into those solutions, usually allowing the solutions to drive the implementation.ย Making decisions about implementations drives you away from abstractions.ย Why abstract something that already exists?ย 

I propose that this is exactly the wrong solution. Instead, you should ask the question โ€œWhat is the abstraction that we need for our solution?โ€ย This is the very essence of what I consider to be the single most important thing you can do in software development:ย Code against abstractions and not implementations.ย The corollary to this maxim is some advice I tweeted six years ago:

Always code as if

IDG

The revelation for me was that if you think in terms of abstractions, and code against abstractions, you canโ€”and shouldโ€”defer your decisions about the implementations.ย The longer you donโ€™t have an implementation, the less likely you are to be limited or driven in a specific direction or decision by that implementation.ย And the longer you let abstractions drive your decisions, the more likely it is that your solution will be uncoupled.ย If all you have are abstractions, then you canโ€™t couple to implementations.ย 

If you decide early on a relational database, and then as the project goes on, it becomes obvious that a NoSQL database is what you need, well, that can be a problem.

Leave the doors open

The goal should be to not even care what database you end up using or which authentication solution you use for your website.ย Ultimately, it will be easier and more effective to fit your implementation to your abstraction than to try to make your implementation match what you actually want to get done with your project.ย If the decision becomes moot, then you have created a system that is well-abstracted and thus well-designed.

This also goes a long way towards solving the biggest bogeyman of software developmentโ€”the unknown unknowns.ย As long as you donโ€™t have an implementation, you have freedom. The longer you can wait to choose or build an implementation, the greater flexibility you have to adapt to the unforeseen hurdles that will always crop up as you build your solution.ย 

Deciding early on what implementation to use is like locking a door behind you and throwing away the key. The best software is built by keeping as many doors open for as long as possible, and by allowing yourself to walk back through the door if what you see on the other side isnโ€™t to your liking.ย Keeping doors open allows you to move forward with more information and less regret.

Now, I realize that the real world enters into this, and ultimately you do have to choose some way to store your data and do your encryption and authenticate and authorize users.ย This isnโ€™t about avoiding decisions. Itโ€™s about making them at the right timeโ€”with the right information. The longer you wait to decide the nuts and bolts of those things, the โ€œcleanerโ€ and more decoupled your system will be, and thus the easier it will be to change and maintain down the road.

So if you ever find yourself feeling pressured to lock in an implementation too soon, stop and ask โ€œWhatโ€™s the abstraction I really need?โ€

The best software is built on possibilities, not premature decisions.

Nick Hodges

Nick has a BA in classical languages from Carleton College and an MS in information technology management from the Naval Postgraduate School. In his career, he has been a busboy, a cook, a caddie, a telemarketer (for which he apologizes), an office manager, a high school teacher, a naval intelligence officer, a software developer, a product manager, and a software development manager. In addition, he is a former Delphi Product Manager and Delphi R&D Team Manager and the author of Coding in Delphi. He is a passionate Minnesota sports fanโ€”especially the Timberwolvesโ€”as he grew up and went to college in the Land of 10,000 Lakes. He currently lives in West Chester, PA.

More from this author