Mark is a graph advocate and field engineer for Neo Technology, the company behind the Neo4j graph database. As a field engineer, Mark helps customers embrace graph data and Neo4j building sophisticated solutions to challenging data problems. When he's not with customers Mark is a developer on Neo4j and writes his experiences of being a graphista on a popular blog at He tweets at @markhneedham. Mark is a DZone MVB and is not an employee of DZone and has posted 553 posts at DZone. You can read more from them at their website. View Full User Profile

The Refactoring Dilemma

  • submit to reddit

On several of the projects that I've worked on over the last couple of years we've seen the following situation evolve:

  • The team starts coding the application.
  • At some stage there is a breakthrough in understanding and a chance to really improve the code.
  • However the deadline is tight and we wouldn't see a return within the time left if we refactored the code now
  • The team keeps on going with the old approach
  • The project ends up going on for longer than the original deadline
  • It's now much more work to move towards the new solution

In the situations I describe the refactorings could have been done incrementally but doing that would take longer than continuing with the original approach and also leave the code in an inconsistent state.

I think the reason this situation evolves consistently in this manner is because although we talk about writing maintainable code, delivery is often considered more important. Pushing out a delivery date in order to refactor code so that it will be easier to work with in the future isn't something that I've seen happen.

Pushing a delivery date out is a cost that we can see straight away.

On the other hand it's quite difficult to estimate how much of a gain you'll get by refactoring to a more maintainable/easier to test solution and that gain will not be immediate.

We therefore end up in the situation where we tend to make major refactorings only if we're going to see a benefit from doing that refactoring before the project ends.

In one sense that seems reasonable because we're trying to ensure that we're adding as much value as possible while the client is paying for our time.

On the other hand we're making life harder for future maintainers of the code base which may in fact be us!

I'd be keen to hear how others handle these types of situations because it feels like this trade off is quite a common one and the way we've dealt with it doesn't seem optimal.


Published at DZone with permission of Mark Needham, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)



Dan Howard replied on Mon, 2010/06/14 - 3:44pm

Good post!  We ran into this situation frequently.  What we do is devote most of the 1st stage of development on the next release to engineering work.  We come back to the areas that had to be "done fast" and do the refactoring on them.   The important thing is to do it as early as possible in the dev cycle to give the QA team the maximum amount of time for testing.



Cloves Almeida replied on Mon, 2010/06/14 - 8:04pm

Delivery IS more important.

When your software is "out in the wilds", I'll get generous and important feedback that will guide further development and refactoring.

If you end up in a situation where code get messed up before deliverying, it's because you're not delivering as often as you should. Fail fast, fail often.

Stephane Vaucher replied on Mon, 2010/06/14 - 9:43pm

If you are talking about significant changes, which affect different modules, I would use the term restructuring as refactoring typically entails low-level behaviour preservation. The difference is subtle as preserving the behaviour of module interaction can be done by breaking low-level compatibility. The reason why this is more difficult is that tool support is not as solid and you need a strong set of integration tests. The value of this kind of restructuring can be hard to quantify.

You need to assess the risk of having hard to maintain code in your code base and consider the life expectancy of the system and the volatility of its requirements. It is obvious that in certain fields, quality/delivery trade-offs are never be acceptable (eg, NASA), but you have to accept that in most cases, it will happen. When in doubt, deliver first (and document). When the system will be in production, you will have a new set of requirements that will change your understanding of the problem (and guide your solution). A more important reason why you should not push delivery for restructuring, is that you will need to plan this restructuring (eg. costs/benefits of different restructuring solutions) and this restructuring might actually fail. I believe the slips you mention could be worse if the restructuring was not managed correctly.

My recommendation would be to make sure your app. is well tested then restructure early in the next iteration (after bugs are finally wrung out). Make sure you estimate the work for the restructuring and have it included (in budgets) when preparing the next iteration. This can be spread out over all functionality (ex: if 1 week, on an estimated 10 week iteration, then add 10% effort). The pill will be easier to swallow that way. Management likes predictability and having options; it appreciates quantifying benefits/costs. You can always talk about technical debt/productivity increase to justify the numbers.

Of course, I know of cases where quality problems got so bad that a development team voluntarily seeded bugs in parts of the code they wanted to restructure. Why? because there was no budget for restructuring, only maintenance.... Sad but true.

Walter Bogaardt replied on Mon, 2010/06/14 - 10:09pm

I'd step back, and approach the problem of time and resources, by how to handle the project. Question wether an more Agile development approach helps in this situation, and leverage some of the tenants of iterations, planning and burn downs to help manage expectations and delivery more efficiently.

Another approach is simply deprecate method's and classes for a more proper design, and implement everything under the new design, and at such a point you have downtime you only have to refactor to use the newer implementation until there is no reference to the deprecated method or classes. 



Peter Veentjer replied on Tue, 2010/06/15 - 12:20am

I like the explain these issues in terms of technical dept to the stakeholder/project manager.

So if a refactoring is big and possible can endanger the deadline, there are 2 possible scenario's:

1) Don't refactor, but the technical dept increases and needs to be solved eventually. If it isn't solved, the performance of the teams slows down (so lots of money is wasted).

2) Do refactor, but accept that the release is going to be slowed down.

Luckily our projectmanager/stakeholder have ears for this situation and allow us to schedule in the refactorings on a continuous basis (in most cases directly into the next iteration(s)). So this means that we can keep the overal technical dept low (although from time to time there will be a small burst). But not every company is so relaxed with this approach.

Small refactorings I like to do on the fly. So if a method is too big, has strange name, too complex etc. I'll do it on the spot. In most cases it is just a few minutes work and decreases the amount of 'broken windows' in the system.

Eduardo Sandino replied on Wed, 2010/07/07 - 1:31pm

Good point Mark... When to do the refactoring ?

As i suggest:

  • if the Team is in a Hurry, just finish the current release.
  • If you do the refactoring while 2 or more people is still working in the project it could be confusing.
  • Better do the refactoring step by step and testing.
  • While refactoring your code fix problems like "cyclic references". To allow you to make automatic Test like TestNG.
  • You should say to the customer that is really necesary to order the code in a way that is really understable to everybody (developers only ;) )
  • If you are working with a project whit many teams is better to loose time designing the system than refactoring the whole project from time to time.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.