After belatedly noticing a truly scary response from someone heavily involved in IT management consultation, where refactoring was described as a waste of resources and a get out of jail free card for incompetent developers, I thought it would be wise to raise the profile a bit.
Refactoring is changing implementation without changing function. There are several approaches to doing it, and as developers we have to be very careful that we don’t change function. Particularly when doing it, if a bug, or implementation fault is discovered. The fix which may ‘simply happen’, or you could do it en passant as it were, is not refactoring. It should be logged, managed and controlled seperately. Issues like this could have been found by accident when fixing another bug or during an enhancement. Refactoring was simply what you were doing when you found it.
Discounting the bonus of fixing erroneous functionality, the next thing you have to be careful of is ‘without changing function’. Functionality is a perception. Say there is a button on your application, the user clicks on it, something happens. You ‘refactor’, the ‘same’ thing happens, but faster. You get a complaint that the progress bar has disappeared, (you ditched is it it was unncessary and now a waste of resource).
Was this refactoring? To me no, that was re-engineering, performance optimisation, or some such.
Refactoring isn’t zero cost, I shall make the argument that is isn’t zero benefit, but it should be zero risk. Of course there is always a risk to one of us typing on top of working cdoe ( :p ) but that should be easily managed. Whatever tests you had in place should produce exactly the same result. If you have no tests, get some before you start, in fact make sure you have the ones you need before you start. They have a value all of their own anyway.
It should be noted that I am talking about production code here, refactoring as step in agile design methodologies, does generally involve a much broader scope of change. Personally I’d describe that as iteration, for instance the progress bar no longer there would be perceived as a positive outcome.
Now the important bit, why refactor?
We are not fixing any faults, we are not enhancing functionality, we are not making changes to enhance functionality in the future we are not improving, performance, robustness, security. Waste of time right?
The only reason for not refactoring, is the code will never need to change again, or it’s so poor in maintenance terms, not even the developer who wrote it could refactor it without changing it. That latter situation of course must be addressed, but that would be re-engineering not refactoring.
For those who come out with the “It should have been done right the first time” argument, no developer would disagree, very few business’s will pay for that though. Essentially that’s a resources argument. A developer good enough to do it, given enough time to do it, a fairly static set of well understood requirements and an unchanging scope, I might add.
If the software was wrote by the cheapest developers you could get, for yesterday, with ever changing requirements and a nebulous scope. “Right first time” went straight of out the window. The business decided that low cost, something to market, good enough and out to market as soon as possible were a higher priority. The above might have been true, it might also be the best business decision, but unless the deliverables are to be thrown away on ‘success’, refactoring is a given. What has really happened is you have marketed a proof of concept or prototype, and ‘lied’ calling it a finished product.
Refactoring addresses the problems inherrent in the general case. We never know enough, changes always happen, and we always have limited resources. It’s very rare, when all three of the above are not true.
In order to change a piece of code you must understand it. A new team member, rotating your team to avoid key man dependencies, simply coming back to something you worked on six months ago, all cause a comprehensibility hurdle. Refactoring, spaces these hurdles further apart, makes them smaller, if you are fortunate, throws them off the track, so they never need be negotiated again.
The goal is to be able to ask any of your team to change any of your code, and they can get straight on with the added business value, instead of spending lots of time learning the code, before they can start the work.
Developers can have long and sometimes violent arguments about what makes codes readable. Use of annotation, doc comments, indentation, meaningful names etc. While two of your developers sporting black eyes may be of concern, whether they have achieved a consensus is far more important. If they haven’t, you may have to referee the next bout, if they have, buy them both a steak.
What you need as a business, is for each of them to be able to understand the code, not their own they wrote yesterday but each others, and last year.
Studies have shown that 60% of the cost of maintaining and enhancing existing code is comprehension. You can address it without formal refactoring, code policing, (takes time), peer review, (takes time), pair development (takes resource), having developers concentrate on one area of the code base (takes resource and causes key man dependencies)
But refactoring to a common level of comprehension, and then refactoring to improve it, is easily the most cost effective and flexible solution. You can incorporate any of the above strategies which can have useful benefits, for instance.
The single business argument against refactoring now and always, is limited resources. An extra day per version on the future versus more than one day now when you cannot afford it. It’s not a cost/ benefit, ROI style problem but a cash flow one. Think of it this way, if you’ve loaned heavily so much of your revenue is used for repayment, paying off a little bit more makes sense. Extending the terms of your agreement to give you the resource to reduce costs and or increase revenue makes sense. Lending more to pay off a loan, defaulting, or crossing your fingers and hoping for a benign external change in your environment, doesn’t, does it? Well unless you are one of the now defunct authors of our current fiscal crisis…
Every time you borrow against future development resource instead of paying ‘cash’ for it now, that is what you are doing.
They say when paying off a debt, every little extra helps, the same is true of refactoring. They say when you are struggling to pay a debt, paying something is better than paying nothing, the same is true of refactoring.
As long as you are refactoring, developers the goal is minimum risk, maximum comprehension.
That’s the technical and the business justification.
My 32.46786 pence worth. Note to self refactor to use currency type instead of floating points….. 😀
So worth saying or not, too technical for the management types, business justification not strong enough?
Edited for a few spilling meskates and such