You know when your code turns into spaghetti and you start wondering what you were eating or smoking when you wrote that code.
Usually nobody is such a bad programmer that writes spaghetti code, spaghetti code is something that builds in time when features are added at big pace or when you implement fixes or “small changes” requested by the client.
Of course ideally you should write perfect code from the beginning but we are not robots and some days you are just stupider or more tired than on an average day. Lucky for me from time to time I get annoyed with my code or have time to kill and then “refactor to the rescue”.
In my opinion there are two ways to deal with refactoring:
1. Do it at the time when you add new code:
For example if you need to add code to an “input processor” class maybe is also a good time to revisit the whole class content and refactor everything. Or maybe you discover that you need to add in fact a new child class to the hierarchy for the new code.
A good advice at this step is to have some kind of code proof tool in your IDE.
For Java my favorite is SonarLint or more advanced SonarQube if you need to have a team/company defined class of rules.
There are plug-ins for the most popular IDEs like Eclipse for Java.
In case of golang you can use the great included tool “go vet” with the same effects.
2. Do it when you are bored of when you have the “what the hell did I wrote here”, or “who is the idiot who wrote this” moments when you look at your code.
A great resource is this simple page with checks from SourceMaking
Or there are great deal of books or online courses about this.
At this stage the most important ideas are:
– identify and reduce the huge methods/functions that do not fit on your screen. If they do not fit on the IDE screen they are already too big.
– try to find repeating code and aggregate it in a separate method/function
– try to use all of the programming language tricks and features to reduce the code while not obfuscating it. I know that C people can compress code that start to look like bytecode but the idea is to still have human readable code not binary 🙂
– separate stuff into short methods/functions. Any modern compiler is able to rearrange code, so having a depth of 6 calls instead of 3 calls is not such a huge difference. The added benefit to this is that you can add very precise unit tests to all this small methods/functions and highly increase your test coverage. There are open source or company policies where if your test coverage for your code is bellow 80% then they consider that you did a sloppy job.
– by using the above rules you are also kind to people. No junior programmer or new person that joins your project likes to end up digging into a 10.000 lines code file with 5 methods/functions in total. As we try to move away from monolith applications we should move away from monolith code.