Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

In reference to broken windows, are there times when refactoring is best left for a future activity?

For example, if a project to add some new features to an existing internal system is assigned to a team that has not worked with the system until now, and is given a short timeline in which to work with - can it be ever be justifiable to defer major refactorings to existing code for the sake of making the deadline in this scenario?

share|improve this question
6  
Sometimes, the boss decides that broken windows won't be fixed, because he knows that he will make much more money by fixing the whole house later. –  mouviciel Apr 16 '12 at 8:05
1  
base rule : Technical debt is ok to reach a deadline, but must eventually be compensated and the sooner the better –  JF Dion Apr 16 '12 at 12:52
4  
Congratulations! You perfectly described the "design philosophy" of PHP. –  ThomasX Apr 16 '12 at 13:06
1  
a curiosity: docs.jquery.com/Won't_Fix –  jonathan Apr 16 '12 at 13:49
4  
Tomorrow never comes... –  Eric King Apr 16 '12 at 14:45

13 Answers 13

can it be ever be justifiable to defer major refactorings to existing code for the sake of making the deadline in this scenario?

  • If something is broken, then most likely not. You won't drive a car with partially-working brakes, would you? (Unless the risk of not getting somewhere on time is greater than the risk of crashing because of the faulty brakes.) Far from ideal solution, but unfortunately it happens.

However, if you are talking about re-factoring working code, then I'd consider the following:

  • If it was up to our senior developers or technical director than we would never release any software. We'd always re-factor and strive for perfectionism.

  • If re-factoring will have a negative impact on profitability of business then it should be re-scheduled.

  • If your business have promised to deliver certain functionality by a given date, then you would refactor later. Think about Red Nose Day charity - every year they can gather donations for a period of 24 or 48 hours. There is no way that they would re-factor their codebase if they thought it might stop them from taking donations in that time gap. Additionally, if there is a broken window, but it won't affect their ability to take donations, then it's quite likely that they will choose not to re-factor.

  • You will always find a better way to do something. It's a natural process and it's very important to be able to draw a line.

share|improve this answer
    
Would be nice to get some feedback on down votes :D –  CodeART May 1 '12 at 18:58
2  
Agreed, with so many minus votes, it looks like someone just had a bad day, and rammed through a bunch of down votes. –  Sam Goldberg May 18 '12 at 20:27

From a business perspective, refactoring is speculative investment - investing time and effort (money) now, in the hope that it will save more time and effort (money) sometime in the future.

Without entering into the debate as to how much the effort to refactor will save in the furture (This depends on too many variables for it to be a meanignful discussion here), it is clear the time to refactor is when the "net present value" of the cost leaving it exceeds the cost of doing now.

Thats easy, except you have no idea how much the furture will cost. You also need to factor in all the normal financial planning ideas such as Return on investment, risk management (value of brand, legal liabilty, insurable vs non insurable risk), oppertuniy cost etc.

In most instances, deciding when to refactor is best left to the people who run the business. Despite what many posters on this forum vocalise, managers usually know more far about running a business than programmers. They have a bigger picture in mind that includes maximising the return to the shareholder. It's rare that fixing things that are not broken contributes to this, code is no exception.

Edit : I have read an interesting article about maintaince schedules on critical infrastructure. The gist is that the movement is away from routine maintaiance (refactor) to repair when needed (fix bugs). The main difference is the monitoring levels - for instance a nuclear power plant monitors in great detail, and fixes when "broken" but well before failure. What has been found is that fixing to a maintaince scheule not only costs more, but is less reliable due outages caused by the maintaince program. A similar idea is required for software - refactor the bits that are about to break - which you can only know by measurement.

share|improve this answer
4  
+1 despite the spelling mistakes :); most times client isn't paying for clean code - they are paying for an outcome. If you have clean code and no results, you don't get paid and you won't be refactoring for very long. –  jasonk Apr 16 '12 at 8:00
2  
I just want to note that it's quite common that Manager have a better sense of the business as a whole. Unfortunately, they often have a far WORSE sense of what the bad code will cost in the future, so make sure your manager has some reasonable cost data to work with, if you're going to trust the manager to make this decision. –  Michael Kohne Apr 16 '12 at 15:41
    
The other way to look at Refactoring is not as something to decide to do as a target task, but as a means to ensure you don't trip over yourself as you develop a system. Often you'll find poorly factored code will cause you to keep modifying tests and trying to put out spot-fires as you go along. This can cost your customer more up front as a result. Keeping code clean shouldn't be seen as gold-plating your code, but as maintaining a professional standard in order to deliver successful outcomes. –  S.Robins Apr 17 '12 at 0:17
1  
@S.Robins We're talking about refactoring, and not poorly factored code, (in my mind the second is a problem, the first is a nice to have). –  jasonk Apr 29 '12 at 20:38

The programmers should let the business side know the extent of the technical debt, so they can make an informed decision. If the need to get to market sooner outweighs the risk of your code, you don't have much choice. Lack of cash flow will trump a lot of technical decisions.

To put some of the problems into a nontechnical perspective, point-out the extended time to fix bugs and add new features. If management has a sales and marketing background, they may understand this. They hate having to tell customers these things will take longer.

If you're thinking about expanding your team, this may be a good time to hire a junior developer. Test coverage will be a huge savior in this case. They'll learn more by doing than by reading documentation.

share|improve this answer

Refactoring is - and should be - an ongoing process. It's not enough to simply meet requirements with a working and tested implementation that is still a little incomplete.

"Make it work, then make it work better".

I can't remember where I read that quote, but this is the key to applying refactoring well, and I count it as unprofessional to do otherwise.

Continuous refactoring is like wiping up the spills while you are cooking, and cleaning your dishes after you've eaten your meal. Targeted refactoring is like finding a dirty kitchen, but only having the time to wash a dirty glass or two. Would you rather live with a continuously dirty kitchen, or would you prefer to keep things clean as you go along?

You get the code to work, then you refactor your code to ensure that you have the best implementation you can possibly use. If you're doing something familiar, it may be that you implement the best code first time, however it bears taking a moment to double-check your work to be sure. If it looks as though you could improve your code, then you try to refactor to make sure your code is at the very least as lean and clean as you can make it. This means you are reducing the amount of technical debt you leave behind, and you make it easier to read and refactor the next time the code needs to be dealt with. This is the core value behind the TDD mantra "Red-Green-Refactor", except that where in TDD you refactor primarily to remove duplication, it pays to also review other items that could be refactored, such as large classes, long methods, and other "code-smells" that can often contribute to technical debt.

If you find yourself facing a major redesign, then perhaps you can put it off for a while, particularly if you are running very low on time in your schedule. This is however provided the functionality of your code will not be compromised, and also provided the implementation will continue to meet the requirements. This sort of situation should be a rare occurrence, and you can help to ensure it is even rarer if you are continuously refactoring as you go along. Even more important however is that you can't risk leaving your major changes for too long, otherwise you will end up creating an even bigger workload later which could either be much more costly to fix, or could end up resulting in an even more costly project failure.

I get the impression that many people tend to confuse the definitions for Refactoring and Re-engineering. The two terms describe strategies to manage very different situations. If you wish to re-engineer, you're making a commitment to make a drastic change which will alter the behaviour of a system. This will invalidate some tests, and will also require new tests. When you Refactor, you are ensuring you're system continues to behave exactly the same as it did before the change, however you are also ensuring that your code will have longevity, and that it will be easier to maintain over time. You're not "pimping" your code for the hell of it, you are committing to a professional standard of clean code that will reduce the risk of failure, and will ensure your code remains a pleasure to work with, and of a professional standard.

Going back to the broken windows analogy, if you break the window you should repair it right away. If you haven't noticed that a window is broken, then you need to decide the cost to you if you leave the window broken. Now, repeat the previous two sentences, but substitute Bug for window. You end up needing a different strategy. If you have created a bug as you code, you fix it right away, or you see if the changes will require a re-engineering effort, and you make a commercial decision as to when it will be best to sort the problem out. So you don't refactor to fix a problem, you refactor to ensure it is easier to find and fix problems. I don't care how amazing you think your code is, complex systems will always have problems that will need to be dealt with over time. This is what technical debt is all about, and why refactoring needs to be an ongoing process as you implement your code, and not left for some arbitrary future time.

So in short, the answer that it may at rare times be acceptable to defer major changes to code in order to make a deadline, however it should not be considered normal practice to treat refactoring as an exercise independent of your daily implementation work, and certainly never used as an excuse by teams unfamiliar with the code base as an option to avoid ensuring that their implementation is as lean and clean as they can possibly make it under the circumstances.

share|improve this answer
    
Like the quote. –  Marjan Venema Apr 16 '12 at 6:22
1  
At too many places "rare times" is the norm. –  Ozz Apr 16 '12 at 13:29
2  
If only the PHP "designers" recognized that quote... –  ThomasX Apr 16 '12 at 13:47
1  
Great quote, Think about this - do you want your car painter to apply the same logic to repairing your 1999 Toyota - and if so, are you prepared to pay for a Roll Royce paint finish on a $1000 car? –  mattnz Apr 16 '12 at 20:51
    
@mattnz Your analogy doesn't really hold true for software development. This is not a case of "gold plating", it's a relatively low-cost down-payment to ensure you get the maximum return on your investment. Stealing your painting analogy, it's also the difference between slapping a coat of paint on your car with a broad brush, or using a spray booth to get a nice even finish. You get what you pay for, so do you want to pay a professional's rate and receive a half-finished job? Cutting corners may save a little in the short term, yet will incur greater technical debt in the long term. –  S.Robins Apr 16 '12 at 23:48

If its really broken then it should be fixed.

But is it really broken? Are you sure you are not just equating "not pretty" with broken.

You need to apply a "sunk value" calculation before you re-factor working code because you don't like the style, or, because you think it will cause problems in the future.

For re-factoring code you wrote last week you sunk cost is the time you spent coding it up last week, not really worth bothering about if the code is substantially improved.

Re-factoring code that has been through unit test. Now you don't just need to re-write, you need to re-define and re-run all the testing done so far, this is starting to look expensive.

Re-factoring code that has gone to production. Even more testing to be done, plus a roll out to the users, and, the risk of delivering something that doesn't work as well as the old release. You need to justify this and clear it with the big boss before going ahead.

Re-Factoring code that has bee in production for a while and been through several releases and bug fixes. Unless you know the software is going to stop working don't even go there!

share|improve this answer
    
Usually "not pretty" goes hand in hand with "broken". Code that isn't written correctly is harder to maintain and add new features to, so eventually you will have to rewrite that code since you neglected refactoring along the way. –  Wayne M Apr 17 '12 at 12:16
2  
Code which is tested and in production with no outstanding bug reports is working code. A lot of time and money was invested to get it into that state. Pretty code is just that -- pretty code. –  James Anderson May 2 '12 at 5:03
    
I disagree. Code can work but be a hassle to maintain and add features to; code like this is broken because it's rigid and "smelly". Code that is written properly is often pretty AND tested AND more importantly is easy to maintain and enhance. –  Wayne M May 2 '12 at 13:37
    
@Wayne M: Wow, Wayne you really have no idea. If you ever make it to PM your developers will love you, but your career probably won't be long. You have to draw the line at some point. I take it it's you who's been downvoting everyone who doesn't agree with your dreams? –  James May 11 '12 at 0:10
1  
@WayneM -- so you would raise a "defect" because you don't like the way the code looks. Code is written to do a job -- if it does the job then its working. Maintenance costs may be high but its gotta be cheaper than a re-write. –  James Anderson May 11 '12 at 1:37

In answer to your question regarding refactoring, I would say, "yes". As someone else pointed out in the answers above, refactoring is an ongoing process, and some times there are tactical and business decisions which supercede the need to rewrite code which is already working (although perhaps in a klugey way).

Regarding "broken windows": I first heard this term in the context of software development, about 10 years ago. But at that time, it was used to describe allowing broken unit tests. This was describing the scenario where people have the temptation to not fix broken unit tests, because it seems more expedient just to remember which tests are "okay to fail", instead of fixing the broken tests (which were validly broken due to interface or requirements changes, for example).

I think applying the broken window metaphor to broken unit tests is more fitting, and more descriptive of the danger of allowing "broken windows" in the software neighborhood. In my opinion, if you were talking about broken unit tests (as broken windows), then the answer would be it is never okay. (To the extent we can ever say never...)

share|improve this answer
    
What's the reason for the down vote? Something said here not correct? Or just vindictive editors? –  Sam Goldberg May 1 '12 at 18:55

It's been my experience that the deadline is the most important thing for the business. It really depends on who's going to use your application. In my case it was for mobile phone OS software... missed deadlines meant missed sales targets and share price hits.

We came across a whole lot of WTF moments when looking at code we inherited and clearly needed to be changed. However because this code worked 'just about' (asynchronicity is poorly understood) there was no incentive for management to actually allow refactoring while there were outstanding commitments to be delivered. It wasn't until a bug was seen 'in the wild' that we'd be allowed change anything, even though we could break it ourselves easily through obscure edge cases. I once refactored approx 10k lines of code in my own time and ended up having to throw it away. The time needed for testing and others reviewing etc couldn't be justified.

share|improve this answer
    
I'm glad the reality of software development seems to be lost on some people –  James May 11 '12 at 0:05

It is acceptable when the damage to the business by fixing them is greater than by not fixing them.

Situations where this occurs might be:

  • where a deadline or business opportunity might be missed because of the time needed to fix
  • where a piece of code is (genuinely) scheduled to be retired in a very short time scale therefore there is almost no benefit to refactoring it.

And these situations do occur - commercial situations will often contrive artificial deadlines which have to be met where the opportunity to negotiate them away has passed, and requirements which have a time component - for instance a change in legislation or tax rules which come into force of a specific date - do exist.

The trick is in identifying these situations and assessing them properly. Code which is scheduled to be retired will often stick around for years. Artificial deadlines may need to be met but they can often be met in different ways (for instance software can be presented, demo-ed and "launched" on a given date without the final release version necessarily being finished until later).

When presented with this sort of thing you need to approach it with an open mind but always ask is it what it appears? Are the assumptions involved realistic? Is there another way of meeting to goal without shipping substandard code? If there isn't how do I best use the time I have available?

And if there is no alternative always fine, but when will we fix this?

Because it should almost, almost, almost always be when, not if.

share|improve this answer
    
Re: artificial deadlines; In the ideal world, any decent project should have a deadline. I've heard of product teams being OK with slipping by a week (a week is no big deal right?) - without realising the business incentive - that this was putting you after black saturday, vs before. Bad move. –  jasonk Apr 18 '12 at 7:55

Some developers say they are "Fixing broken windows" when really they are "rearranging the deck chairs on the Titanic". Refactoring code that works but offends your sense of smell is relatively easy. If you find that you keep coming back to that sort of task instead of adding new capabilities for your users, or making the app more usable for them (optimization meaning making the app run faster is good here, optimization meaning making the code more readable is different) then perhaps you are tidying up too much. Not because tidying up is bad, but because the company is paying for development in order to get something developed. They don't want a brittle, hard-to-read, poorly architected solution, to be sure, but they also don't want a polished and beautiful half-solution.

Tidy up when you need to do something simple "to get going", or when you're waiting for another team to tell you whether your problem is in fact their fault, or when you're waiting for a decision. There will be plenty of opportunities. If you have the chance to move the whole app forward, take it, unless you are starting to feel the whole thing has become brittle. It probably hasn't. You will get a chance to refactor - you don't need to worry about that.

To come back to the second half of your question, a sprint to add features facing a short timeline, it would be wrong to say "and we won't be doing any refactoring, there isn't time." It would also be wrong to say "I know it's been 6 weeks and it looks exactly the same to the users, but these broken windows really needed to be fixed." Fit the refactoring into the gaps that happen in any project. Don't take refuge in tidying up at the expense of meeting the goal of the project.

share|improve this answer
3  
Some developers say they are "Fixing broken windows" when really they are "rearranging the deck chairs on the Titanic" - indeed, it often seems to be difficult for developers to tell the difference between "technical debt" and "not the way I would have done it" –  RevBingo Apr 18 '12 at 11:52

You can think of it in the same way as asking for credit. Is it ok to borrow money to invest in X in the short-term, and pay for it on a long-term basis? There is no definitive answer, it can be in the best interest of the organization (e.g. to meet current client expectations), or it can be a disaster if done irresponsibly.

It all comes down to priorities, and management should be aware that although the number one priority is to make "code work", implement new features, and meet the customer expectations, every time you leave broken windows you are making that number one priority slower, more difficult, and requiring more resource investment. Also, 99% of the time it is not feasible to stop developing new features and concentrate every effort in "fixing the codebase".

In conclusion, yes it is acceptable to leave broken windows sometimes, just like it is acceptable to ask for a loan...just remember that you really, really have to pay for it in the future. And in the future, the time to do it will most likely not be that much greater than the time you have now.

share|improve this answer

Most programmers are in the business of making money for their employer. So when should refactoring happen: When it makes your firm money. Refactoring is time spent not spent on other projects and time saved in the future on this project.

Whether it's worth it is mostly up to your manager.

share|improve this answer
1  
-1; This kind of attitude is what causes software systems to fester because refactoring is seen as "time that could be spent on new things". –  Wayne M Apr 17 '12 at 12:07
1  
Refactoring IS time not spent on new things. –  Pieter B Apr 17 '12 at 13:13
    
@Wayne M: Things is software engineers usually don't get to decide what things get done, the business and managers do. Of course, everybody would like to get to refactor whenever they wanted, but it's really not the reality... at least in my 7 years experience in the profession. –  James May 11 '12 at 0:07
    
+1 This kind of attitude is what delivers value to whoever is paying your salary. Without it, your whole job could be outsourced. –  MarkJ May 14 '13 at 17:29

Normally, when you are able to, you should fix it, This will prevent potential time spent for maintenance. However, some barbaric non-agile practice tends to let the status quo as it is as long as it is working. Some managers are afraid of the "unforeseen effects" of the change.

My take is to leave it only if it is working as it should ( only broken by optimization but not functionality) and you lack the time to test it, if you do some refactoring. However, you should note that it should be fixed later as soon as possible.

If its broken by functionality and you new features depend on it, it would be best to fix it ASAP as well.

share|improve this answer

If managers decide that they want to build up technical debt. This is a fair decision to make if one, for example, just want an early prototype out to some initial customers to get some early feedback.

share|improve this answer
4  
It happens far too often, where managers allow technical debt to accrue to meet a tight deadline, only instead of paying off the debt as quickly as possible, they see the next deadline looming and instead of scheduling in time for up coming work and prior debt, the debt is ignored and the time needed filled with additional new features for release. In other words, the debt is never paid off, and before yo realizes how deep in hock the project is, it's too late to do anything to avoid the problem spiral out of control. It's OK to accrue debt, so long as you actually pay it off quickly. –  S.Robins Apr 16 '12 at 0:22
2  
Some managers (especially non technical) have no idea what you are talking about when you mention technical debt. Some even think you are trying to con them into just going away and playing with stuff instead of doing real work. –  quickly_now Apr 16 '12 at 8:24
    
That is the reason why our organization does not have managers: Open-Org.com ;) –  David Apr 16 '12 at 15:46
1  
Most managers aren't intelligent enough to understand the drawbacks of technical debt, so what you end up with is technical debt that continually accrues until you go technically bankrupt and are forced to rewrite the entire system. –  Wayne M Apr 17 '12 at 12:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.