This month I’m going to discuss ‘Refactoring’ within the context of developing, maintaining and improving a Moodle plugin.
The principle foundation for the discussion is a book by ‘Martin Fowler’ (en.wikipedia.org/wiki/Martin_Fowler_(software_engineer) and martinfowler.com/aboutMe.html) called “Refactoring, Improving the design of existing code”, ISBN 0-201-48567-2 , first edition 1999, Addison Wesley Longman Inc.
Disclaimers and license
Moodle™ is a registered trademark of ‘Martin Dougiamas’ – moodle.com/trademarks.
Other names / logos can be trademarks of their respective owners. Please review their website for details.
I am independent from the organisations listed above and am in no way writing for or endorsed by them.
What is refactoring?
In his book, Martin defines this as “the process of changing a software system in such a way that it does not alter the external behaviour of the code yet improves its internal structure”. Therefore I understand from experience that I sometimes need to change a the code of a plugin such that it then becomes:
- In a state to add new functionality.
- Improved readability and reduction in duplicate code for the purpose of bug mitigation. You remove duplicate code such that if when improving the plugin you change something and then forget to alter the other same place where the functionality is the same.
- Smells bad.
The latter is referenced in the book as ‘Bad smell’. That the ‘code’ smells bad, so you have a feeling that it is just wrong for some reason. If your computer actually smells bad then you should do something about it! So that feeling draws you towards thinking what is actually wrong and what you can do about it.
Once created all Moodle plugins tend to evolve over time. This happens even if their functionality is not changed because Moodle itself changes with releases. Therefore a given release of a plugin may not work on a newer version of Moodle. This means that it needs to change and evolve if it going to survive. And thus the plugin changes without actually appearing to the user to be any different.
So given this, what happens when you request that a new piece of functionality is added to a plugin and the developer agrees? They will go away, have a think, look at the code and consider what the new functionality would alter. Even if it can be written, can it actually be added without breaking anything? What then needs to happen to add it on?
Like in a candy shop, if you go “ooh, I’ll have one of those and one of those and ooh, one of those” then as individual items they will be nice, but as a combination then they could make you feel very unwell. The same is true for combining functionality. Adding something new changes the overall look and feel of the plugin. It has to be considered to not only be of benefit but to actually make sense within the context that the plugin exists in.
So, the developer has performed some analysis of the new desired functionality and considered its impact. As a result of this, they have decided that refactoring needs to take place before it can happen. But there is a cost being ‘time’ and possibly ‘money’! But then you say “but refactoring won’t add anything, so why should I pay for it?”. The answer to this is the need for it to happen such that:
- Its actually possible to add the new functionality.
- Less chance of introducing bugs.
- Less future maintenance time.
all being in my experience.
Just like the ‘candy shop’ example, going around in circles blindly changing things without thinking is a bad thing. Consider the scenario where you have given the developer your ideas and worked out a design with an outline of what it should do. The developer then goes away and ‘magically makes it happen’. All is good and you’re happy. The developer has carefully structured the code to fit what you want. But then you think, humm, perhaps it would look better if ‘that’ changed. You inform the developer and they make the change. So far, so good. But what happens if you do this again, and again and again? This is where problems can happen. The code is ‘re-jigged’ over and over to cope with the changes. In the end you’ll have a mess! Then in order to make the code work properly, refactoring will need to happen as a process of making sense of the mess. So when things are tidy then the bugs can be found and eliminated.
Therefore it is better to think about what you’re trying to achieve. Work through scenarios of how the functionality will be used with your users. Far better to get things right at the start than the end. Then you’ll save both time and money.
What happens next
Once you’ve worked out the design and functionality to add along with the need to refactor, then the next step is the refactoring itself before implementing the functionality. This involves choosing the ‘refactorings’ and confirming that nothing has been broken after they have been applied. Then the new functionality can be added.
What about course design?
Courses with their materials evolve and need to be updated to cope with change. So how is this different from software development?
Therefore, has the Moodle course you’ve written evolved over time? Is it now in a bit of a mess? Does it ‘smell bad’? If so then do you think you could apply the same ‘refactoring’ concept to it? And that you won’t actually change the course, but restructure it to be in a better position to be updated and accept new materials (functionality).
Refactoring is an essential part of maintaining and improving software to enable it to survive and grow. Understanding what it is and why it is required will help you to understand why developers need to expend time performing it. It is also perhaps just as true for courses.