During a longterm exposure to a hard-to-maintain monolithic applications full of legacy solutions, it’s hard to keep a good attitude and motivation. This guide is a set of 10 good thoughts and ideas how to cope with such situations and improve on two fields: personal skillset and the code quality.
To rewrite or not to rewrite.
This is the question most of the teams maintaining and developing a legacy ever-evolving applications are being asked all the time, or keep asking all the time. Or at least have in their minds all the time.
This is sometimes a hard question and sometimes it’s not that difficult. However in any case it’s beyond of the scope of this guide. This guide is aimed at people who need to work with such code, even if there is a major rebuild effort going on or one is planned — sometimes we just need somebody to handle that legacy thing which “is just working” and is the stallion of the business.
So you are in a maintenance team, or you are in charge of one. Or you are just a lone wolf who was hired by an owner of some legacy monolith everybody is afraid of. First of all — don’t worry, be bold. Let’s start with few significant moves which will give you good direction of your quest.
1. Use VCS
Somebody can’t imagine software development without proper
Version Control System - they got so used to it. Do you know that there are still some who can't imagine that something like VCS exist? If that's your case start with a good
.gitignore file and do your
Initial commit and never look back.
2. Force the formatting whenever possible
Pick some good formatting convention for the language and platform you have. And force it and I mean it. Setup an automatic linter, fix existing codebase as much as possible. Don’t forget about trimming whitespaces and adding ending lines, if needed convert everything to
UTF. Then run the linter on every code change.
Why to be so dramatic about that? One great tool to work with legacy, often bloat code, when nobody really knows how it works are diffs, between versions and changes, don't waste resources and your power for diffs polluted with whitespaces.
3. Embrace current architecture
Since you are reading this you probably need to carry on with some really big codebase. Big enough that you cannot refactor it in a week. Let’s embrace what you have.
Take the code as it comes, try to find good sides of current solution. That’s important for further work but also for your motivation, don’t be overwhelmed by the difficulties the current solution pose.
Answer the simple question — what’s good about the project? Maybe it’s following some industry standards or some common patterns. I’m sure when you look at that code you have already 10 better solutions coming to your mind. But is it actually that bad? Worse not mean bad. Find good bits, note it down, you will need it just in a moment.
Now be the rigorous judge. List all weak parts. Possible threats for the maintenance, for the security and further development. Remember that your are now responsible for that thing. Be clear what is the current state.
5. Find your own way
So now you should have the good sides and the bad sides. The R&D department which starts a new project from scratch, have an ease saying where it should end up being in a defined future. You can’t, you should precisely know where you are right now, but the future is mostly unknown.
Your daily work can be driven by short-term goals which can kill any great long-term technical roadmap. Let’s face it and instead of doing a complex “where we wan’t to get” plan, focus on an ordinary guidelines set for everyday work. That guideline will shape your application and your future work.
Draw a line between the good parts and the bad parts. Select those you simply cannot accept — mainly any security threats or serious instabilities.
- define the way you want build new features and change existing ones
- then define what you want to modify slowly over time — “I will replace that part in following way every time I will came across such implementation”
- plan a more intense rebuilds to the unacceptable parts, if possible schedule a mini-projects for the condensed work to remove the weakest parts
Stan bold on a daily basis
When you did that preparation phase, you need to get to work. Create your own daily work environment, both with tooling and procedures, to help yourself and your team be more self disciplined and to enforce on low level ideas you planned on high level.
1. Decide on the workflow
Decide how you want to handle daily maintenance and development. It will relate to the project management systems your organisation already have, so let’s add technical support for it. Pick up some VCS flow — for example GIT flow. Decide how you want to test, review and deploy the releases. What the release would be for you. Stick with some versioning patterns. If possible try to create and maintain the
2. Setup application environment
The chances are, there is some production environment up and running for the application but there may not be any staging, testing or development environments and tooling.
If there is one present, approach it the same way as the codebase itself — make use of the good parts and remove bad parts. If there is nothing, create it. Start with local development instance, then staging and testing. Think about CI/CD and have a 12 factor apps rules in mind. That discipline pay with time. Don’t rush, if the project worked without complete framework it will continue to work fine.
3. Ensure monitoring and alerting
If not already present add basic interval monitoring to measure the uptime. Add error handling, maybe some initial logging. You care about your patient, so make sure you know when it get worse.
When you set up error monitoring don’t forget to keep checking it regularly. Once in a month could be too rare.
4. Do code reviews
That works best when there are at least two developers in the team. Keep the code reviews the most important tool in ensuring that your maintenance and development roadmap is executed, one line after another, one pull request at the time.
If you are alone pull requests with diff can help — at least you will have a clear view into what changes you are applying and which one could cause that nasty degradation bug you detected with your monitoring tooling (it’s always the race who will spot the bug first, you or the user, or the user who is a friend of your boss).
As a part of every code review run your lint checks and test suits.
5. Improve your high level guides
Make sure that your everyday routine can improve your high-level plans and roadmaps. Take time to iterate over your main maintenance & development guideline. Do a retrospective what worked and what didn’t. Fix that and be self-reflective.
Whenever you come across interesting case try to document it. It will help you with the retrospectives and it… will help those guys which will take over that project after you and start the whole story again.