Are refactoring tools, such as those in Eclipse, changing the balance of importance between various stages of the software development lifecycle? If so, is this a good thing?…

It was recently brought home to me how long it’s been since I’ve done a big chunk of Java programming. If you exclude my JSP spam filter (which has been ticking along nicely for years now in Googlesque perma-beta) and the time-tracking tool, which is written in Jython and is more Pythonic than Javaic (sp?), then I haven’t done much Java in several years.

This explains why I thought it was time to roll up my sleeves and do some coding. In the last couple of days I’ve put together a simple Euchre game written in Java. It’s playable, but not yet ready for public consumption. I’ll post it when it’s in a better shape. Instead, this post is inspired by the tool I’ve been coding in: Eclipse.

Intelligent IDEs

Back in 2003, when I was doing full-time Java development, we used Borland JBuilder as our IDE. I haven’t tried an updated version of JBuilder, but I’ve been really impressed by the tools that Eclipse has to offer. And I’ve got a feeling that I’ve only just started scratching the surface.

In particular, there is a whole menu dedicated to refactoring your code. For example, you can rename a function and the IDE will go through the rest of the code and make the necessary changes. There are dialogs and wizards for all manner of refactorisations, from extracting constants to introducing factories. Very exciting stuff, and I look forward to using these things to re-design my code as I go. And, with that, we reach the purpose of this post.

Up-front high-level design

Traditional wisdom has been that up-front design will save you time and money in the long run. When I first started programming, I didn’t do any design at all. Of course I didn’t, I was only ten! But I did get stuck in and do coding, and I created useful software. I had a rough idea what I was trying to achieve, and as I was only programming for my own benefit I could do whatever I wanted. Big programs got unwieldy, and changes took longer and longer. Perhaps the big boys were having the same problems on a larger scale.

The traditional waterfall model of software development has a big chunk of design. More modern iterative and agile methods split these up, but still have up-front design and recommend design before coding. Prototypes are often considered dangerous – create them if necessary as a proof of concept, but then throw them away and start again with formal requirements and a clear design once you better understand the problem domain.

The move to code-based design

Now that there is good tool support, it is cheaper than ever to refactor broken code.

Suppose we let everything flow outwards from the code:

  • requirements: codified as unit tests
  • high-level design: generated from the code, not created separately
  • low-level design: generated from the code (using technologies such as Javadoc)
  • implementation: always has been coding
  • testing: automated (in the code) as much as possible
  • refactoring: changing the code directly with an IDE

At the very least, bringing these artifacts into the codebase helps to keep them in sync.

Whereas today each iteration might have up-front design followed by implementation and small-scale refactoring (with testing throughout), perhaps the design is decreasing in importance and the refactoring is increasing. This seems an altogether more agile approach. Part of the refactoring process would involve generating design documentation from the code (for example, UML class diagrams), inspecting these manually or automatically and then refactoring as appropriate. But the key point is that these are generated from the code, not created up front.

I’m not anti-design. I’m just floating this as an idea, and you’re welcome to put your own points of view across in the comments below. But there does seem to be a general trend towards a code-first approach in other stages of the development process, so perhaps the time will come when it subsumes high-level design as well. As long as the refactoring is taken seriously, perhaps supported by a tool-chain for enforcing coding standards and general de-linting, there’s no reason why the quality of the final product should suffer.