-


 
Home > Careers > Story Print this Page|  Email this page

Refactoring: A matter of quality

In this third article of the series on Extreme Programming (XP), PRADYUMN SHARMA looks at another important XP practice called refactoring, which is an ongoing process to improve the quality of existing software

Suppose you had designed some software two years ago, and had subsequently implemented it, tested it thoroughly and successfully deployed it for some client. You also know that you had done a good job of its design and implementation, applying sound practices of software design, appropriate design patterns, etc.

As commonly happens, some time after commencing its usage, the customer came up with some minor changes in requirements, which you could easily incorporate in the system because of a good design and good documentation (I seem to be kidding here, but let us anyway assume so). Sometime later, some more changes in customer’s requirements, and therefore, some more modifications to your code. A new report here and a different validation there, and some more code got modified further. Such modifications, mostly minor, have been going on for quite some time now.

Now today, you get yet another minor enhancement request from the client. As you start looking at the related code, you suddenly realise that over a period of time, the small changes made by you to some class, or a group of related classes in a package, has resulted in that code becoming overly co-mplex or inelegant. Or, one class ending up doing too much work that does not logically belong to this class.

Software decay

As you look at some more classes, you find that it is not an isolated case where a class that was compact, efficient and elegant two years ago, is no longer so. In short, you are encountering a kind of software decay.

Like everything else in the universe, software also decays. Though unlike tangible things, software does not decay by just using it, but due to changes made to it in order to meet some short-term goals.

How does one normally respond to software decay? Most of the times, by just cursing one’s predecessors, and proceeding to make more changes to the concerned code in order to meet the new requirements. And in the process, contributing further to the software decay. Over a period of time, the software becomes more and more messy.

As the original developers get out of the picture, and new people get involved in the project, they find it increasingly difficult to maintain the software. But nobody has the courage to overhaul the system and clean it up. After all, nobody wants to risk breaking something else and take the flak. By now, perhaps there is nobody who fully comprehends the structure of the entire system.

But how should one tackle software decay? By adopting the XP practice of refactoring in your project.

Introducing refactoring

Refactoring is the process of making changes to the design of an existing system in order to improve its quality. You take a bad piece of code, and make some changes to it with the intention of making it simpler to read and maintain, or more efficient, or more in accordance with the good design practices. When you are doing refactoring, you are not adding any new functionality to the system, but making it easier to do so in future.

Martin Fowler has described the principles and techniques of refactoring in his celebrated book titled Refactoring. This book discusses the guidelines about how to identify where refactoring is requ-ired, and how to en-sure that it is done in a safe manner. For anyone wanting to master this craft, this book is an essential reading.

Refactoring has to be done in a controlled, disciplined manner without chan-ging the external behaviour of the code. The structure of the system should be improved, but without introducing new bugs in the system.

Examples

As one simple example of refactoring, you may find that a method in a class has become too large, obfuscating its purpose. You feel it would be better to split that method into smaller ones, each having a distinct sub-task to handle. Go ahead and do that. This is anyway simple, because no client of this code gets affected by it.

Somewhere else you may find that a lot of subclasses are duplicating similar code. It may be better to move this common code into a superclass. You can do this also without affecting any client code.

As a more complex example, somewhere you find that a class is doing some work that should be done by some other class. This involves not only moving the method from one class to another, but also modifying the code of the clients of this class, so that they make a call on a different class.

In some other place, a method in a class may need more information from its caller. You can simplify this interaction by passing the required information as a parameter in the method. This change also req-uires modifying the interface of the class as well as code in its clients.

Refactoring and testing

At first, such changes may sound scary. You are now going to make changes in multiple places within your application. But how do you ensure that while it improves the structure of your system, it does not break something else that has been You can do this refactoring with confidence if you have already understood and implemented the XP practice of testing (discussed in the previous article of this series). In fact, automated tests are a must for doing these refactorings with confidence. Any class that is going to be modified must have such self-checking tests.

If you do not already have automated tests for the code being modified, you now build such a test suite. Go through the code that you intend to refactor, and create tests for them first.

Then, refactor your code. But don’t release the modified code unless it passes all the tests again. If any tests fail, it means that your refactoring has broken something that was working correctly earlier (of course, it may also mean that your tests are wrong, so it is important that the tests themselves are written carefully and verified before they are run).

Continuous refactoring

Begin refactoring in a small localised manner. Keep refactoring wherever you find a scope for improvement. You may have to alternately switch between a development role adding new functionality, and a refactoring role cleaning up earlier code.

Once you have a clear picture of the problems with the overall structure of a system at a large level, you may then even consider big refactorings, involving altering the system architecture, changing the key inheritance hierarchies in the system, etc.

Refactoring should be an on-going activity, and not just left for maintenance stage problems. In fact, once you master the practices of refactoring and experience its benefits, you will find that it is no longer critical to have a watertight design before commencing any coding. Indeed the design keeps evolving as the development proceeds.

Pradyumn Sharma is the CEO of Pragati Software, Mumbai. He is a trainer and consultant in the area of object technology. E-mail: pradyumn.sharma@pragatisoftware.com

<Back to top>


© Copyright 2003: Indian Express Group (Mumbai, India). All rights reserved throughout the world. This entire site is compiled in
Mumbai by The Business Publications Division of the Indian Express Group of Newspapers.
Please contact our Webmaster for any queries on this site.