This blog is about converting legacy code better—using architecture already in place, SOLID principles, and best practices.
Generally speaking, not having an architectural plan set up (or not using SOLID principles and best practices) can lead to passing the buck to the next generation of developers. We should all strive to push good code forward to get the latest and greatest out there. Starting with following the patterns in place at your job, or SOLID best practices, will make converting and upkeep way faster in the future.
This post contains a discussion of my experience in various software team environments. Throughout them all, we show that if SOLID patterns and best practices had been followed, then time spent converting code would have been less and code upkeep would have been easier down the line.
SOLID Principles + My Software Architecture Philosophy
A key topic of this blog is SOLID. It is a mnemonic acronym for five object-oriented design principles intended to make software designs more understandable, flexible, and maintainable. S.O.L.I.D stands for:
- S – Single-responsibility principle
- O – Open-closed principle
- L – Liskov substitution principle
- I – Interface segregation principle
- D – Dependency inversion principle
If you have yet to look into SOLID, I encourage you to do so now. (Also check out these SOLID Keyhole blogs Refactoring: Ugly Code That Does Everything and Four Ways Of Writing Thoughtful Code To Think Less)
Before getting started with my experience, I want to give additional detail for where I stand on the software architecture structure:
- Project names, class names, method names, variable names, etc. should be descriptive
- Each public method should have a summary comment on it
- Names should NOT have ‘AND’ or ‘OR’ in them
- Each logic method should do ONLY ONE thing
In most cases, legacy code has a great deal of technical debt, and most teams want the conversion and upkeep done as quickly as possible. The act of following the architectural plan set in place and using SOLID principles when converting code, allows for easier maintenance, high cohesion, low coupling, and saves time and effort when updating code in the future.
I deem a past project of mine “Architectural Overkill.” In this case, the Software Architect was the all-encompassing role, where things could not move forward without their say-so.
If this sounds familiar, you might be in an architectural overkill scenario such as this one: You look at the code in an effort to convert, upkeep, and take notes about how it should be converted. Additionally, you’re looking to see if any code is new or has questions about where to go. You send the notes to the architect and wait for a decision.
In my case, the legacy code used both SQL Server and Oracle, while the new code used Azure. I got answers that SQL and Oracle were still maintained and used. So my first thought was to separate the data access layers into a SQL and Oracle DLL. Since everything was still maintained and working, this would have been the use of SOLID and best practices without keeping the pattern in place. After sending my notes and thoughts to the Software Architect, it was deemed that I needed to get a list of all stored procedures and tables that were missing in Azure for the database team to move over. As a senior developer ingrained with SOLID principles, I felt comfortable making a decision about where certain code should go. However, that type of decision-making was limited solely to the Software Architect.
Pro: One upside to this is that every developer, no matter the project, all follow the same patterns. So in the case that you jump teams, the code will look the same across the company.
Con: The architect is the bottleneck of this operation which can significantly hamper productivity in certain scenarios. In my experience, it was like pulling teeth to add new modules, DLLs, or determine what kind of unit tests to use.
Tip: To combat downtime in this kind of structure, the best approach is likely to do conversion of the code using SOLID and best practices in a separate branch. This provides you with a few critical things. One, the code is already converted and can be moved where needed. Two, you are already ahead of the game if that’s how the architect prefers it.
Team Lead Architect
In my experience, getting answers about the code is usually faster if the team lead is in charge of software architecture for a project. Additionally, you can ask the other senior developers if the team lead was busy, and they will also know the answer.
Pro: When downtime is limited, getting answers immediately helps convert the code to how it will end up – as opposed to guessing in a throw-away branch.
Con: One drawback could be team jumping, which may lead to different patterns used on other teams. But generally speaking, sticking to best practices is the most effective approach for everyone involved.
Free For All
Alternatively, you face a major problem with technical debt with a lack of software architecture. At another company, I was put on a team where every developer coded their own way. There were developers that would put all the code inside one method and others that would create new DLLs for each part of the code.
Unsurprisingly, this place also had a high turnover rate. In this case, developers would be forced to pick up unfinished code and take over. I found myself in this situation, trying to get a uniform software structure across the team to no avail.
Although there was no downtime (waiting on how to code something) (pro), when you took over a project or looked at legacy code, it took forever to get up to speed (con).
Best Practices: Does Everyone Know Them and Follow Them?
The ways in which an organization sets up its software may differ, but as a general rule, beginning with the SOLID principles is a great way to set you up for success.
Keep in mind what other developers know and how they code. People coming from new jobs may have that pattern ingrained in their coding style, and that can be hard to break out of. I was guilty of this when I left my first job of 7 years. When I used the coding style I had learned and used at my old job, I discovered that my new environment didn’t follow the same patterns. Rather, I had to adapt to and learn how my new job had things set up.
Overall, I’ve discovered that most jobs follow some form of basic SOLID principles, especially when converting legacy code. When joining an established team, it’s common practice to give new developers simple tasks to get up and running on the software—easy bugs to fix or convert/upkeep legacy code.
As a new developer on a team, there is no problem with a lead saying, “let’s get you started on keeping up this old code. We need to add this functionality as well as move it to the latest .NET or CORE… asynchronous if possible. Extract all of one thing first, test if it still works, then move to the next.” I’ve found this to be a great approach to basic code upkeep/converting. In fact, I still use this pattern when updating legacy code to this day.
Tip: Another helpful tip is moving code to what it pertains to, such as database calls going in the Data DLL or new business logic going in the business logic DLL. This will assist future upkeep and conversion since the code is already laid out for you. It will also free up the time used on explaining where the code went and how it works now.
Using Best Practices like SOLID for Future Incoming Developers
It’s crucial that all people working on a project are on the same page regarding how best practices work in that project’s structure.
If done correctly, any developer should be able to pick up code with knowledge on what is going on and where code should go. The ability to pass code over to another developer and have them pick up where it was left off helps speed up production, will reduce the technical debt acquired, and allow for new code to be added with ease.
Limiting the time used to gather information about code is a key goal when doing converting/upkeep of legacy code. Keep in mind, most newly hired developers will have some knowledge of SOLID or best practices, and will hit the ground running faster with that architecture already in place.
Learning SOLID and best practices is a fairly painless process. There are videos all over the internet that can aid in explaining how it works, here is one that I found helpful.
That said, there will be a number of developers that do not know SOLID or best practices, and that’s okay. For full disclosure, I was not aware of them until my third job out of school. I knew of patterns, but not a universal architecture that should be used as the base for all coders.
Some places will have patterns and best practices in place, while others will be running on autopilot—using whatever structure they’ve found works to get it done. If you find yourself at a place with no set structure in place, please adhere to best practices and SOLID principles of coding. More than likely, this will be the acceptable coding style. It will also speed up the updating of the code later on. Setting yourself up with a known and acceptable pattern makes updating and converting easier, leading to less time spent coding down the road.
If you’re a Software Architect or Team Lead in charge of setting patterns for code at your workplace, remember to take into consideration just how long a pattern will take to understand. The ability to pick up where code was left off speeds up production, reduces the technical debt acquired, and allows for new code to be added with ease.
In the end, we want to spend less time producing quality, readable code for the client. Starting with SOLID and best practices will not only make the code easier to manage, but it will help get new developers spun up on the project. It’s a win-win for everybody.