See the first post in The Pragmatic Programmer 20th Anniversary Edition series for an introduction.
Time for a little quantum mechanics with Schrödinger’s cat. Suppose you have a cat in a closed box, along with a radioactive particle. The particle has exactly a 50% chance of fissioning into two. If it does, the cat will be killed. If it doesn’t, the cat will be okay. So, is the cat dead or alive? According to Schrödinger, the correct answer is both (at least while the box remains closed). Every time a subnuclear reaction takes place that has two possible outcomes, the universe is cloned. In one, the event occurred, in the other it didn’t. The cat’s alive in one universe, dead in another. Only when you open the box do you know which universe you are in.
No wonder coding for the future is difficult.
But think of code evolution along the same lines as a box full of Schrödinger’s cats: every decision results in a different version of the future. How many possible futures can your code support? Which ones are more likely? How hard will it be to support them when the time comes? Dare you open the box?
This challenge is a great thought experiment to conduct for existing codebases, although it is somewhat difficult to draw generalised conclusions about due to the reversibility of certain a decision being highly contextual. However, I will provide discussion on some of the points I considered (there were many).
I imagine that the authors have used the rather vague phrase ‘possible futures’ to force the reader to consider some of the ways in which the future may change for a software project. Some high level suggestions:
- Technology trends/innovation
- i.e. Programming languages, frameworks, cloud computing e.t.c.
- Industry/Business domain trends/innovation
- i.e. Introduction of online grocery shopping in the mid 2000s
- Evolving business needs
- i.e. expansion into new geographical locations, entering new product markets, targeting different customers, complete product shifts, acquisitions e.t.c.
In general, most widely used programming languages have the ability to support many ‘possible futures’. They are a tool and can be used to build many different solutions - a hammer can be used in building a shed or a boat. Of course some languages are better suited to certain tasks and some may be practically impossible to use - C# is likely better for Windows based applications than Java but both will work, whereas building an iOS app would likely be impractical with Erlang.
As frameworks provide functionality for more specific domains than a programming language, they are somewhat less future proof. Large shifts in technology trends/innovation or business direction may force a change of framework, however evolution through changing existing features and adding new ones is generally not an issue. Django is great for web applications, but shifting the product to the desktop, or mobile would require an entirely different framework (although Django could be used as a backend to such applications). Furthermore, in a well designed software project, core business logic should be decoupled from the framework - allowing for the choice of framework to be reversed and replaced with a different one.
Often at the very core of software, databases can be difficult to change for a variety of reasons:
- Poor design may lead to database queries being scattered throughout the business logic of an application
Drastically different data models may require changes to which values are retrieved from a database and how they are used
- SQL vs NoSQL vs Graph
Exporting/Importing data from one database to another
That said, motivation for changing a database (other than CV-driven development) usually stems from a new feature that is separate/additional to the existing application and can therefore often be used alongside the existing database. For example, Elasticsearch can be used to provide a powerful search engine on top of an existing SQL based application.