Click here to view the complete list of archived articles
This article was originally published in the Spring 2003 issue of Methods & Tools
Refactoring Java Code - Page 2
Oliver Whiler, Agris Software
When should one consider refactoring?
Ideally, refactoring would be part of a continuing quality improvement process. In other words, refactoring would be seamlessly interwoven with other day-to-day activities of every software developer.
Refactoring may be useful, when a bug has surfaced and the problem needs to be fixed or the code needs to be extended. Refactoring at the same time as maintenance or adding new features, also makes management and developers more likely to allow it, since it will not require an extra phase of testing.
If the developer in charge finds it difficult to understand the code, he/she will (hopefully) ask questions, and begin to document the incomprehensible code. The phrases he/she coins may be a good starting point for the names of new methods or classes.
Often, however, schedule pressures do not permit to implement a clean solution right away. A feature may have to be added in a hurry, a bug patched rather than fixed. In these cases, the code in question should be marked with a FIXME note, in order to be reworked, when time permits. Such circumstances call not for individual refactorings, but for a whole refactoring project. When the time has come to address the accumulated problems, a scan for FIXMEs, TODOs, etc. over the code base will return all the trouble spots for review. They can then be refactored according to priority.
What are the benefits of refactoring?
Carrying out a few refactoring operations before or during code debugging may have immediate benefits. Often it becomes easier to spot the bug location. So time is saved, while at the same time the quality of the code is enhanced. Well-structured code is also less error-prone when it comes to extending it.
Kent Beck [Fowler, p.60] states that refactoring adds to the value of any program that has at least one of the following shortcomings:
Summarising, while sometimes there are immediate benefits to be reaped from refactoring, the real benefits normally come in the long term. They consist in substantially reduced time that developers spend on debugging and maintenance work, as well as in improved extensibility and robustness of the code. In addition, code duplication is reduced, and code re-use fostered. Overall maintenance and development cost should come down, and the speed of the team to react to changing needs should improve.
What are the concerns, particularly of management?
If there are so many usually undisputed benefits from well-structured, comprehensible code, and if refactoring leads from chaotic, badly structured, error-prone code to well-designed code by performing a serious of small, controlled operations, why then is not every software developer engaged in refactoring?
Software developers are often reluctant, because some refactorings are simply tedious. And there is no visible external benefit for all the labour put in.
Also management may be at fault. As long as management only rewards externally visible code properties such as functionality and performance, but neglects to pay attention to the code’s inner quality, e.g. via code review or by failing to set coding standards, it is only to blame itself, when software developers are reluctant to invest some of their precious time on refactoring operations.
Then there is the serious risk of breaking the code through refactoring operations. And if e.g. file-names change, traceability of modifications is likely to become an issue, too.
Even if the software developer, is keen to refactor some badly structured code. His/her manager, however, may have quite a different perspective, and may oppose any attempt to modify working code. These concerns cannot simply be ignored, but must be suitably addressed by both developers and management.
Why use an automated tool?
When doing refactoring the externally observable behaviour must be guaranteed to stay the same. If refactorings are carried out manually, one needs to frequently rebuild the system and run tests. Manual refactoring is therefore really practical only, when the following conditions hold:
This situation is not very common, meaning that the applications of refactoring is limited. This situation is becoming more common, particularly as more people use XP (Extreme Programming) development methods.
Another hindrance is that many of these refactoring are tedious. Potentially requiring hours of precious development time, as the change is made and then thoroughly checked. Not many programmers would enjoy the task of renaming a method in a large code base. A simple search and replace will potentially find extra results. So each replacement must be examined by the programmer. However there is no great intelligence to the operation, all that is wanted is to rename any use of a method on a given class or its subclasses. A refactoring tool therefore can save hours of work. Even more importantly give confidence that the correct changes were made.
The speed of automated tools has another benefit, which is shown in team development environments. A developer is much less likely to perform refactoring operations if the source code involved is under the responsibility of other developers as well. However by using an automated tool, the refactorings can be completed quickly so that other developers are not held up waiting to make there changes when the refactoring is completed, or worse making their changes on the old code at the same time as the refactoring operation. This ensures that even when the responsibility for a section of code is shared, developers will not reach a stale mate, where none of the developers make the required changes.
Integration with the developers chosen IDE also bring many benefits. Firstly having the tools at hand, means that developers can more easily refactor. They do not have to switch between development and refactoring modes, and can instead see it as part of their normal development cycle. Secondly IDE features such as Source Control Integration can reduce the effort in refactorings such as move class or rename package.
Conclusion
Refactoring is a well defined process that improves the quality of systems and allows developers to repair code that is becoming hard to maintain, without throwing away the existing source code and starting again. By careful application of refactorings the system's behaviour will remain the same, but return to a well structured design.
The use of automated refactoring tools, makes it more likely that the developer will perform the necessary refactorings, since the tools are much quicker and reduce the chance of introducing bugs.
More Java Content