You should never be afraid to refactor your source code. In this post I take a look at refactoring, and how it can help to make your software better.
It is already a commonly held assertion that refactoring source code is good practice. There are many excellent blog posts about this topic. This view is so entrenched in the world of software development, that any good Development Environment comes complete with refactoring tools. Some development methodologies go as far as to include time for refactoring in the development cycle and insist that it is done.
Some might feel that such forced refactoring is overkill. Whatever your view on that, if you encounter a piece of code that could be improved upon you should never be afraid to refactor it. It might look like a lot of work. You might feel the effort outweighs the benefit. Perhaps you feel it’s something you can put off to another day. Unless you are on a tight schedule, if you can find the time to change that code, then don’t wait, do it and do it now.
Quite often a piece of code is written with a very narrow goal in mind. Sometimes that goal grows as the software grows. Other times you find yourself writing similar pieces of code that have distinct differences but essentially do the same thing. Eventually you will reach a point where it is clear the original code can be improved upon. You can change how it is called, to make future implementations of it easier. Alternatively you can create a common routine that can be shared by many functions. When you spot such a chance to make an improvement, it is time to do so.
More often than not these types of changes also provide the opportunity to eliminate bugs or improve performance:
- By creating a common way of handling a process, you can fix a bug by just changing one section of code. You also remove slight variances in the way you do things that could introduce bugs.
- Creating a library of tools for common tasks often encourages you to think about more efficient methodologies. Improving efficiency of one common function applies to all areas that use that function.
How to Refactor
Whilst you should never be afraid to refactor, this calls for some understanding on how best to do so. There are a number of things that can be done to improve on existing code. Here are a few of the more common situations and ways to handle them.
1. Code Reuse
It probably started simple. You needed to write a piece of code that fulfilled a particular situation. You then had to write another which did something similar but not quite the same. So you copied the original and changed what needed changing. Then the same happened again, and again. You end up with dozens of routines, all essentially doing the same thing. Each of these routines need maintaining separately if you want to expand on that functionality.
The solution to this is to look at the common areas of the code. If something is being done the same way each time, then break it out into a new function. Use parameters to the function to govern how it achieves the the different goals of each call. In some cases it might be a little more complicated than just passing a different set of variables. If there are key differences in processing, these can be achieved with callback functions.
2. Long Parameter Lists
Another one that started simple. You created a function to fulfil a role. You found it could be used in more and more situations, but needed to add further parameters to it to do so. Eventually you end up with a function that takes a dozen or more parameters. Half of the parameters are not needed for any one given task but have to be set to something.
One solution is to consider creating a parameter object. It is a simple object that has properties for each of the functions parameters. The object’s properties are set to default values by its constructor. When you instantiate the object, you only need to set the required properties. When you call your function, you pass the object as the only parameter.
3. Code Reuse and Long Parameter Lists
It’s not uncommon for the above two situations to coincide. You try to avoid code reuse by creating a function, only to find you encounter a long parameter list. There is another approach that can be taken to this.
The solution? Rather than a parameter object that is passed to a function, the object becomes the home of the function. You start setting up properties within the object. The function is a method of the object and can be called without parameters. The added advantage of this is you can create more methods on the object, so if your properties are suitable for several functions, they can all be shared. You can also create inherited versions of the object’s class to handle specific variations in the function, thus avoiding the use callbacks.
A relatively new approach to setting up an object with lots of properties is to use chaining. This is an approach where a Set method is used to assign a property’s value. The Set method then returns a pointer to the object it belongs to. This differs from early object implementation where Set rarely returned anything. By returning a pointer to the object, a successive number of Sets can be called in a single line of code.
There are many other ways that refactoring can be accomplished, I have listed just a few. But hopefully you now feel inspired to refactor that old routine and never be afraid to refactor again.
SAMWare UK creates bespoke solutions and websites. Contact us to arrange a chat to discuss your needs and for a free no obligation quote.