What is and how to approach code refactors
Every business goes through this, every developer at some point in their career complains about this. Businesses are scared about it and rightfully so, because if done wrong it can lead to a lengthy process of eventually producing the same complex problems in a different form or even worse, introduce new ones on-top of the old ones. Great!
How does a refactor happen?
Simply put, poor planning or if proper planning, then poor execution due to either inexperience or not enough time given to allow the solution to mature. When programs are built with delivery as the prime factor in value, the result is poor quality. This is why we have $5.00 t-shirts that tear in the dryer after the first wash. Getting the product out was more important than making the product last.
At some point in a business life-cycle, the PO or CEO will have an idea for a feature in their platform and reach out to a developer. A developer looks at the code base and to his bewilderment, the relationships and functions within the code seem to resemble a fine pasta dish at a lovely Italian dinner down the street. Unfortunately, we're not out to lunch, but the feature definitely is.
The code base has become so complex, ripe with duplication of code routines, magical functions and bad practices to "make the darn thing work for this sprint!". The result is those complexities compound and eventually the system becomes so fragile and complex, that adding a new feature to it, breaks an older feature that the business now depends on. No more shortcuts no more bad practices and no amount of pleading with a developer will fix it. Your code base.... Needs the dreaded refactor in order to develop the new feature (event b) to have it integrated into the system (event a).
Fine, but then what is a refactor?
What a fine question to ask! A refactor is when you reiterate over a solution and factor out the complexity that it is within. But then you ask, what the hell is complexity? Well, that's complex you see, it could be that one function has to now wait for another function to complete in order for that function to execute because it depends on some variable x that isn't available until the first function runs <--- that sentence, is complexity and you may ask what's so complex about it and I may be so kind to tell you, that complexity is the relationship of 'things' that depend on each other in order to achieve another 'thing' and 'how' those things interact with one another matter with respect to their complexity in the matter.
I still don't get it, can you explain it another way?
To get a sense of what a refactor it is, it helps to understand what a refactor isn't. A refactor is not a re-write. A re-write is when you completely ignore all the problems that have arisen from creating a relationship of business solutions through code, over an extended period of time, in different times sensitive environments. Now we may say that now we are going to start from square one and redo everything from scratch and because we control the time better we now have ourselves as much time as we need to create a solution that is far far far better than the first monstrosity. Why? Because, we won't be so rushed and we can develop a better solution as a result of not being rushed!
And it is at this point, I ask to you, in the kindest way possible. WHAT are you planning to factor out of the old solution that will make the new solution better?
Isn't that something? We never often stop to ask simple questions when such complexity arises, unless of course we are in the fields of scientific endeavour.. Yet, in the industry of technology, in which it is derived out of the very key observations of electricity, electromagnetism and conservation of energy, we seemed to have lost this notion of asking deeper questions to the thing we are trying to solve! I don't know why that is.. Perhaps people have become to accustomed to using the word "following a standard".
Refactor is about asking questions first, coding last, not vice-versa. It's about reasoning about the problem AND the solution.
We cannot refactor any code without truly understanding the relationships of the problems, problems to the solutions, the set of both against any side effects. The deep question we must ask in the refactoring process is :
What is connected to what?... And WHY?
This single question when viewing the code to be refactored opens up so many new perspectives to understanding how to solve the problem of reducing the complexity of the relationships within the code base without even writing a line of code, even a character of code.
A developer with this mindset, will tinker. Create branches to test how different functions behave when a dependency in some deeply rooted file nested three levels deep into the structure of the application is changed, removed, modified, abstracted or moved in close proximity too.
This is the discovery process and the discovery process is to understand the effects, side effects and the nature of the whole scope of a single problem in a sea of other problems. We're trying to get a foothold do the understanding of these complex relationships!
When the problems are identified (defined), that is when you can organize the work for the refactor into deliverable products that provide value to the business and something else remarkable happens, parallel processing! We can develop new features and also code them in ways where we can expect that at some point X in the future, the dynamics of how the code looks, is structured or behaves will change and we can expect it.
Approaching Refactors Correctly
- Ask what is connected to what and why.
- Perform analysis on the moving parts to see how they work.
- Perform synthesis on moving parts to see how putting them together with new solutions or 'ways' affect the application.
- Experiment, experiment, experiment
- Document your findings, document your findings, document!
- Get perspectives on various solutions and choose one that best fits and is agreed upon.
- Organize all the solutions into a deliverable cue, story or epic.
- Approach your refactor like regular work. DO NOT re-write. Refactors can be done in the same time your do other work. But it must be supported and the problems must be known and truly, deeply understood. The problems only arise when the problems are not deeply understood.
The goal of a refactor
Businesses often don't see the goal or value of a refactor. Refactoring is actually part of a very natural phenomena in nature. All things in nature behave like this. Cells become complex and large, they under go a process in which they divide and refactor themselves. When a Government agency becomes to big and has a wide range of authorities, it's often broken up into smaller municipalities, or divisions, such as the Federal Government vs Provincial Government.
This process is called disintegration, not to be confused with a laser disintegrating in some action thriller, but the literal words dis-integration. The integration of relationships going in the opposite order of combining.
Through this process of disintegration, better organization, clarity and performance can be found, if the process is done correctly. If for example, the refactor of a hospital system included factoring out the scheduled appointments cue into surgery and checkups, perhaps some efficiency is found, however this has no impact on emergency wait times. So wait times in general stay roughly the same and the same problems persist but now in a new form. A bad refactor.
I hope this provides some clarity on the subject!
-Dan