views:

524

answers:

22

Should I prepare my code for possible/predicted future changes so that it's easier to make these changes even if I don't really know if these changes will be required anytime?

+1  A: 

In a word, yes.

In a few more words, you should always make your code as readable as possible, include comments, and always assume that at some time in the future, you will be called upon, or someone else will be, to modify the code.

If that someone in the future comes across a block of code, uncommented, unformatted, with no indication of what it does or should do, then they will curse you forever :)

You're not actually answering the author's question. They're not asking about making code maintainable. They're asking about designing code to handle future changes (that may never happen).
Tom
A: 

In two words: yes, always.

Marc
A: 

What you describe is part and parcel of being a good developer.

See On Writing Maintainable Code

Galwegian
+2  A: 

Scalability in your code is one thing you should always consider.

The more time you spent today in catering for scalable solutions, the less time you will spend in the future when actually expanding

Andreas Grech
+11  A: 

Within reason and certainly if its not much effort.

I don't think you can always apply this, as it can make you over-engineer everything and then it takes too long and you don't make much money. Consider how likely the client is to implement something, how much extra it will take to prepare for it now and how much time it will save later.

If it requires a lot of work, but makes sense to save money, you could raise it with the client.

I seem to be in disagreement with a lot of people here, who say always - but I've seen a lot of things where effort has been put into make future features easy to implement ... but they've never been implemented. If a client hasn't paid for the time spent making the feature easy to implement, that's money straight off your bottom line.

Edit: I think its relevant to point out that I'm coming from an agency environment. If you are working on code for yourself, you can probably predict future development with a greater level of certainty, and so its probably feasible to do this in more cases.

benlumley
Here here, I support the "Only when needed" cause. :)
Xetius
Yeah, it depends.
cretzel
I've never regretted making the code adaptable. However, as you say, it can be done badly. This is where learning from more seasoned programmers is invaluable.
Mike Dunlavey
+2  A: 

Predicted or very likely changes - yes, generally it's good to have them in mind.

"Take anything that might ever happen in the universe into account" - no. You don't know what could happen, trying to cover for everything unknown is just over engineering.

NeARAZ
+4  A: 

If you work in a refactoring-friendly lanuguage I'd say NO. (In other languages I'm not sure)

You should make your code as loosley coupled as possible and keep things as simple as possible. Stay specific and dont generalize to unknown use cases.

This will make your code base prepared for the things the future will bring.

(And frankly, most anticipations of the future tend to be sufficiently off-mark not to warrant coding for it today)

Edit: It also depends on what you're doing. Designing apis for external users is not the same as developing a web app for your company

krosenvold
A: 

The obvious answer is YES. But the more important question is how!

Orthogonality, Reversibility, Flexible architecture, Decoupling, and Metaprogramming are some of the keywords that address this problem. Check out chapters 2 and 5 of "The Pragmatic Programmer"

I find it is generally a better strategy to design a "change-accommodating" architecture than trying to specify specific changes that might (or might not) happen. It is a good exercise, though, to ask "What may change in the future?", and then resist the temptation to prematurely implement potentially unnecessary features, but rather have such possibilities in mind when creating the application architecture.

Ola Eldøy
+7  A: 

yagni.

http://en.wikipedia.org/wiki/YAGNI (*inserted by friendly editor :-) *)

fix the bugs in that horrenous code you're writing today.

refactor when the time comes.

Leon Bambrick
+15  A: 

I am likely to get lynched for my opinion on this, but here I go.

While I have had this hammered into me over years of reading idealistic articles and sitting through far too many seminars and lectures categorically stating the nirvana like benefits of this, I too had similar questions in my mind. This line of thought can lead to massive over-engineering of the code, adding many man hours or more to design, development and testing estimates, increasing cost and overheads, when in reality this is not often the case. How many times have you actually reused your code or a library. If it is going to be used in many places, through numerous projects, then yes you should.

However, most of the time this is not the case. You will often find it more economical (in time and money) to only refactor your code for reuse and configurability when you actually know that you are going to use it again. The rest of the time the real benefits are lost.

This is not, I repeat NOT, an excuse to write sloppy, poorly designed, poorly documented code. This should be a fundamental that is so wholly ingrained in you that you could not break it, but writing a class for reuse is a waste most of the time as it will never get reused.

There are obvious exceptions to this. If you are writing third party libraries then obviously this is not the case and reuse and expansion should be key to your design. Certain other types of code should be obvious for reuse (Logging, Configuration etc.)

I asked a similar question here Code Reusability: Is it worth it It might help.

Xetius
I guess I've never bought into the term "re-use" as a means of making code adaptable, because it seems to result in an overblown class structure. That alone makes it hard to adapt. I guess I would teach OOP a little differently.
Mike Dunlavey
+2  A: 

Remember that most of you code will be changed/refactored. If you know that you will have to change your code within the next week, prepare it. But don't start making everything exchangeable and modular by default. Just because "maybe in the future" you shouldn't create a framework, if three lines of code do the job for now.

But think twice, if the system behind makes refactoring difficult (databases).

Marcel J.
+3  A: 

Yes -- by doing less.

You won't know what the future requirements for your code. The best preparation for the future is not to implement anything that's not needed right away, and have good unit-test coverage everything you do implement.

mfx
A: 

I find that there is a parallel here to something I heard on test-driven development recently. The person talking about it had observed that while at first it could be a little annoying to always write unit tests and think about how your code can be written to be testable, it turned out that at some point it just begins to come naturally to write test friendly code.

The point is that if you always write with modifiability in mind, you might end up doing it more or less by reflex, thereby making the overhead of writing the extra code very small. If you can reach a state where high quality, extendable code is what comes naturally to you, I think that would definately be worth the initial cost. I do still believe, though, that you must to it in moderation and that sometimes it's just not the right thing to do for a given customer.

Morten Christiansen
+1  A: 

No, never. Write good code that is easy to reuse/refactor but preparing for half thought out enhancements is, imo, the brother of premature optimisation; you'll likely end up doing things you don't need or that push you down a certain (possibly non-optimal) design path at a future date. As mfx says, do the minimum required now and unit test everything; it makes extending code a doddle.

Patrick
A: 

Two simple principles to follow:

  1. KISS
  2. Always avoid dependencies

Thats a good start

DonOctavioDelFlores
A: 

Yes, but only by writing maintainable, easily refactored code.

You should definitely NOT try to guess what might be required in the future. Such efforts are not only pointless and time-wasting for your current targets, but are more often than not counterproductive when any future changes become apparent.

Jim Cooper
+2  A: 

One thing I learned in my mere year of coding for the company I work for, everything you do, no matter how perfect you think it is will come back haunting you for an update or needs to be altered because client X suddenly decided not to like it.

Now I am making my code highly customizable so when that day comes to do some adjustments, it would be ready in no time and I can continue with my work.

Drahcir
A: 

This is really important. It needs to be done well, but takes experience.

If I count up the number of edits (via "diff") after implementing a typical requirements change, numbers like 10-50 are common.

If I make a mistake on any of them, I've inserted a bug.

So personally, I always try to design to keep that number down.

I also try to leave instructions in the code for how to make anticipated changes. If I'm maintaining code, I really appreciate it if the prior author also did this.

Mike Dunlavey
A: 

To balance the effort with the benefits is the skill of design.

Not all our code needs to be flexible. Some things will not be changing.

No wasted effort. Finding the right parts to devote our attention to.

Tricky.

LenW
A: 

Yes, always think of where your code may need to evolve in the future. In the current project I am working on there are thousands of files and every single one of them has atleast one revision to it. Even leaving aside bug fixes plenty of those revisions are to make way for additional software features.

ddcruver
A: 

I wouldn't change my could to prepare for an unknown future feature.

But I would refactor to get the best solution to the current problem.

danswain
A: 

You can't design against an unknown (future), and as other people have said, trying to build a flexible design can easily lead to overengineering, so I think that the best pragmatic approach is think in terms of avoiding things that you know will make it harder for you to maintain your code in future. Every time that you make a design decision, just ask yourself whether you are making it harder to change things in future, and if so, what you are going to do to limit the problem.

Obvious things that will always cause problems:

  • Scattered configuration information - you need to be able to check and change this stuff easily
  • Untested code - you need tests to make changes with confidence
  • Mingling of storage and output concerns with the core logic - you will switch database instances and output formats, if only for testing
  • Complex architecture - you need to have a clear mental model of the system
  • Arrangements that require manual intervention or updates to keep them running
Stuart Ellis