Where I work developers are always telling me that "I added this just in case for the future" or "I think it's a good idea to do this because they'll probably want it some day". I think it's great that they're proactive in trying to anticipate future changes but I can't help thinking that it's unnecessary and risks writing code that may never be needed and therefore unproductive (I also think that some developers just want to try out something new for the sake of it). Are the arguments for future proofing invalid if you just write good, clean organised code?
Well first of all, there are some things that need clarification:
- Future proofing is not adding stuff.
- Future proofing is making sure you can easily add code/features without breaking existing functionality.
This means is that writing "future proof" code, is ensuring that the code is written in a loose coupled manner, sufficiently abstract, but also code that does not completely hide abstraction levels, so there's always a way to go to the lower abstraction levels if necessary.
Writing future proof code is an art by itself and is tightly coupled with SOLID practices for component versioning, separation of concerns, layering and abstractness of functionality. Future proofing has nothing to do with adding features ahead of time, but with making sure you can add features in the future in a non breaking manner, through the good design of existing code/libraries.
It is important to realise that making code future proof, and writing code in case it is needed in the future are two very different things. The former is crucial to a good application, the lesser is usually not good coding practice.
For me, future proofing the code, is writing it in a way that it will be able to interact with evolving technologies. This involves modularising your code, so that each part of your application can interact independently of the language and technology of the application as a whole. A good example of this would be using XML or JSON to pass data between different parts of the application. However technology evolves, it is very likely that it will always be able to read XML and JSON.
Similar to the above, exposing a part of your application via a SOAP or REST API achieves a similar thing. Whatever technologies evolve, you will not necessarily need to re-write every part of the application because new technologies will still be able to communicate with old.
On the point of writing code in case it is needed, I think that it is very dangerous as the code is likely to have little or no testing.
So, by all means, make code future proof (NASA still send spaceships up using Fortran), but dont write code 'just in case'.
Do not write code that will not be used for a long time. It will be useless as it most likely will not fit the needs at that time (which you by definition do not know yet).
Make the code robust against unexpected problem situations allowing for graceful recovery or fail-fast, but do not write code for possible future uses.
A good way to ensure that, is to use test driven design and development. Test cases are derived from the specification and use cases. All code must make a test pass. Unneeded code should not be written. By doing it this way it is simple to determine if it is needed or not.
Think about how many time you have enabled a piece of code down the line in a production environment and thought, "Thank god I wrote that 2 years ago!".
Code should be modifiable / extendable easily. Don't add code that isn't immediately necessary, because this gives a very false sense of security and wastes dev/test resources in a world of changing requirements.
A lot of the other answers address kind of larger design issues, or are rather abstract. If you think in terms of what will happen in the future you can define some clear techniques to help future-proof the code.
Primarily think that in the future somebody will try to add a feature to the code, or will attempt to reuse your code somewhere else. They may also try to fix a feature in the code. Obviously just having good clean code is a required starting point, but there are also some specific techniques that can be done.
Defensive Programming: Do input checking beyond what you current application actually needs. Whenever you call APIs be sure sure to check that their input is something that you would expect. In the future people will be mixing new versions of code together, so the scope of errors and API returns will change from what it is now.
Elliminate Undefined Behaviour: A lot of code has behaviour which just kind of evolves from nowhere. Certain combinations of input lead to certain output which nobody really intended, but just so happens. Now inevitably somebody will rely on that behaviour, but nobody will know about it since it isn't defined. Anybody attempting to change the behaviour in the future will inadvertently break things. Use safety checks now and try to remove/block all undefined uses of the code.
Automated Test Suite: I'm sure you can find volumes written about the need for unit tests. In reference to future proofing however this is a critical point in allowing somebody to refactor the code. Refactoring is essential to maintaining clean code, but if lack a good suite of tests you can't safely refactor.
Isolation and Segregation: Encapsulation and proper modularization is a good design principle, but you need to go beyond that. You'll often find that you need to use a library, or API, or product, which may have a questionable future. Maybe due to quality concerns, licensing problems, or continued development by the authors. In these cases take extra time to put a layer between you and this code. Slice down the API to just what you need so the coupling is very low to allow easier replacement in the future.
"Future Proof" at best means "loosely-coupled design". 80% of the time people mean "flexible" when they say "future proof". Sometimes they say it to try and sound cool. But at least they're delivering something on time that works.
"Future Proof" at worst is meaningless. 20% of the time, it's an excuse to waste time researching alternative technologies instead of simply delivering something. They're not delivering anything (or what they're delivering is too complex for the problem at hand.)
There are two edge cases.
Unfailing foresight. One actually can predict the future accurately. In this case, please apply this powerful foresight to future proof the code. Better, apply the unfailing foresight to predict market trends and retire early and stop coding.
One is "driving" the future. That is, one has some new technology ready to deploy in the future that will require a rewrite of the thing being delivered right now. That's weird that one is not deploying this cool future thing first.
We must deliver project "A", knowing that project "B" will lead to an immediate rewrite of "A". In this case only, we might be able to future proof "A".
Ignoring the title of the question, and sticking the main point about "putting stuff in because somebody might want it some day"...
The answer is NO. Never. Don't write a stitch of code you don't need today. Here's why:
- The program is now more complicated than it needs to be.
- You may never need the feature, so you've wasted your time.
- You don't know what the requirements for the feature will be if anyone ever asks for it in the future. So you'll have to figure it out and modify it anyways.
I think the first point is the most important. If you've ever worked with a system that's riddled with generic code for different customers, or full of feature bloat with stuff you don't need then you know just how much extra time and effort it takes to maintain or extend the functionality because of that. So avoid at all costs.