Have you ever shaken your head in disapproval while reading code when you were working on a project? Have you at least once thought to yourself: "This isn't optimal code – it's possible to write it better and more efficiently"? Does adding or changing a theoretically small functionality on your page cause countless problems and require introducing changes to many other areas? If the answer to at least one of these questions is "yes", it may be the time to plan code refactoring.
What does it mean to refactor code?
Code refactoring means fighting technical debt. It's a process of transforming chaotic code that's non-compliant with standards and good practices into clean code, the structure of which is simple, understandable, and extensible.
What's clean code?
Code is considered clean if everyone on the team is able to understand it easily. The functionality provided by clean code may be easily extended by all developers on the team, not just the code's developer.
Clean code is characterized by:
- being understandable for other programers,
- lack of duplicates,
- being fully tested,
- easy and cheap maintenance.
Step 1: Learning about an application or website
At the beginning of a code refactoring process, you should carry out an in-depth analysis of the application and highlight the elements that are difficult to develop and maintain. A helpful method during this stage (and at the same time – one of the refactoring methods) is Exploratory Refactoring. What is it about? Set a timer for 25-30 minutes and refactor the functionality you want to understand during that time. At this point, it doesn't matter that the changes you introduce aren’t optimal or that the code stops working as it should. The purpose of introducing changes at this point is to thoroughly comprehend the functionality and understand the legacy code that you're coming to refactor. This approach reduces the time required for analysis – static code reading will almost never give you a complete picture of the situation.
Step 2: Writing down the things that may be a problem
Hey, I choose to work on the "AplicationManager" class. It hasn't been tested at all. It has many responsibilities. It's also very fragile and has a typo in the name. This 250-line method, which has seven parameters and two flags, maybe broken down not into a few methods but into three classes. I came to these conclusions during an Exploratory Refactoring, and also found out that we should…
This is one example of the result of using the Exploratory Refactoring method. During the analysis, write down the problems you've encountered and the possible solutions to these problems. This list will be necessary for the correct and optimal process of designing the refreshed application. Don't focus on details at this stage, don't try to define exact solutions – there'll be time for that.
What things may pose a problem? In many cases, we may feel that there's something wrong with the code. It affects so many people that such a hunch even got its own name – code smells. The code smells may be grouped and used for iterative refactoring.
I know that this class already has 648 lines and many dependencies and responsibilities, but I quickly added one method because I needed it for my task. This class seemed appropriate to me. What? Why have I already done this six times in six different, unrelated tasks? As I'm telling you – it's just a quick fix.
Code is bloated when it's so large that it takes a long time to understand, maintain, modify, or extend it. This type of code is expensive and difficult to test. It's characterized by:
- long methods,
- long classes,
- long list of parameters,
- duplication of variables in multiple classes,
- using primitive fields instead of simple classes.
Partial or inappropriate use of object-oriented programing
The code collects all the abuses and incorrect use of object-oriented programming – it breaks the rules, loses its readability. Changes, maintenance and testing, become more expensive.
The code smells list in this case includes:
- duplication of functionalities,
- comprehensive switches that may be eliminated using polymorphism,
- temporary variables in the method.
Changing the class causes the need to overwrite theoretically unrelated methods. This extends the time it takes to make improvements or extensions to the code.
Redundant elements of code
- During Code Review, I came across the $fooMaganer variable, which you commented as "Foo Manager variable, used to manage the Foo". Do you think this is a proper comment?
- I don't know, but our standards state that each variable has to be commented on, not that the comment is supposed to contribute something. So how will it be? Will you approve?
Redundant elements include anything that adds nothing to the code or isn't used. Among them are:
- code excessively filled with unnecessary comments,
- code duplicates,
- unused code,
- unused classes,
- unused methods.
Hi, Adam, Anna needs a list of the first ten numbers in the Fibonacci sequence. Please, give it to me, and I'll pass it on your behalf. Thanks!
Connectors are redundant elements of an application, the task of which is only to call a functionality implemented in other classes and pass the results to the calling class.
- methods that mainly refer to another object,
- classes drawing from internal fields and methods of a given class,
- call chains,
- classes whose sole responsibility is to call a method in another class.
You might also like: Software Development Tools that Boost our Productivity
Step 3: Designing the refreshed application
After identifying and describing the problematic areas, it's time to plan the main process. Refactoring may be carried out in an iterative or holistic manner. It all depends on the amount of time you can spend on the process. The holistic approach obviously takes more time, but the benefits of using this approach are greater than with the iterative approach. The latter is a method of refactoring changes, consisting of improving selected elements of an application. The iterative approach may be divided into correcting a specific code smell list and full refactoring, but only of particular functionality.
How to refactor code? Summary
Refactoring is a process that reduces the cost of introducing changes and new functionalities to an application. It benefits everyone, from the project owner, through the development team and testers, to end users. Clean code is easier to test. As a result, the process of implementing changes to the production becomes less stressful. If introducing changes to your website is time-consuming and the code is fragile, it's time to consider refactoring. Starting this process will bring you long-term benefits.
If you have a website or application on Drupal and you don't know how to refactor your code properly, our Drupal support team will help you with that.