When we start working on real software projects, it’s very likely that the team you’ll be joining will have an existing source code rather than starting a project from scratch.
Every source code comes with its own set of technologies, patterns, practices and policies, and that’s when we run into this problem of not knowing where to start or how to understand what this code is doing especially if it’s a massive source code.
Often times documentation will not be available, and if it is, it might be outdated or high-level design that may or may not be fully followed or implemented across the entire project.
The only actual and truly reliable documentation you have is the code itself, and possibly the people who wrote it (if they are still around) — everything else is at best a 50:50 chance.
So, if you found yourself in a situation like this, what can you do to understand the project you’re working on? How can you minimize your learning curve and maximize your contribution to the project?
There are a few things I have learned in the past 15 years that I’d think might benefit you in situations like these:
Domain First (The Big Box)
The first thing you should do, is invest most of your time trying to understand what business is trying to achieve through the software. Keeping this overview in mind will help immensely.
Understanding the domain will help you pinpoint where the code is headed as an end goal, which will tremendously help you determine which of the existing code can stay and which of it can be completely removed from a high-level perspective. This should play a big role in decreasing the complexity of the code and will make it much easier to understand.
Understanding the domain will help you regionalize the code, that is, being able to see bigger regions of the code as big blocks that you can move around and see the relationship between each and every one of them.
Architecture (Lego Pieces)
Along with the domain understanding, you should focus most of your efforts on seeing what flow the code is following in order to accomplish its goals.
Some source codes are harder to understand than others from an architectural perspective, especially if the architecture isn’t very familiar or common. Your best bet would be finding the architect that originally designed the software to learn from him or her in terms of what the original intent may have been.
Understanding the architecture will help you greatly in knowing where the code is following its original design and where it went off the rails and violated its destination to get something done.
Being able to see where the code is violating its high-level design will help you see the cohesion between the components of code that actually follow the rules, and it will give you even a better idea of how to bring the off-design components back into the original design, which should eventually contribute to the quality of the source code and the project as a whole.
Allocating the time for refactoring and rebuilding existing components that “just work” is a whole different topic that I have discussed in a different article.
Patterns (Smaller Lego Pieces)
There are so many different patterns to write software, creational, structural, behavioral and others.
Understanding what patterns the code is or was trying to follow will help you see on a class-to-class level how features are intended to be built in the code.
It will help you write a cohesive code that follows the agreed-upon patterns which will eventually result in a lot less code review comments and a lot faster ability to deliver features and resolve defects.
It will also help you see again the parts of code that violated these patterns, so you’d understand which is meant for consistency and which is crying for refactoring.
Coding Guidelines (The Nitty-Gritty)
In most teams, you might come across a coding guideline, a set of rules the team agreed on to follow to create a cohesive class-level code that is easier to read and understand.
If the team you’re joining doesn’t have a standard coding guideline you should reference the universal coding guideline for the programming language you’re using and make sure everyone on your team is on the same page.
A cohesive code that is readable plays a big role in your understanding of where things are going from a low-level perspective.
Someone might ask, where do we get all that information about the domain, the architecture, patterns and guidelines?
There are few methods you could follow and I recommend diversification of these methods in order for you to get all the information you need to learn about a certain project:
1. Find all possible documentation, even if it is outdated, and build a knowledgebase around common terms, abbreviations and concepts your team is using to refer to certain features in the system.
2. Once you build your knowledgebase, you can now communicate with the program managers and engage them into domain discussion about what the software is trying to do from a business perspective.
3. Communicate with the architects and team leads about what high level architecture the software is following. Then go read or watch as many tutorials as you can about that architecture and its best practices, and then engage in discussion about what you think is violating the standard architecture to get a better understanding of how the system is designed.
4. Be sure to communicate with the developers and engineers on the team to understand what patterns are followed and what coding guidelines are enforced to maintain the code, then again, go back and study about these patterns and run comparisons to find where it best fits to follow the pattern and enforce the guidelines.
5. Start doing some clean-up work and fix potential defects to get a deeper understanding on the code-level to grasp deeply how the team communicates their thoughts through code reviews and fully understand what they recommend for a better clean-up work procedure.
Refactoring is always a great opportunity to engage the team in a discussion of what the best practices are and what guidelines should be revisited and what others should be enforced.
6. Share your findings and your documentation with the team, gather them in meetings and continue engaging them in constructive discussions about the business, the architecture, the patterns and the code itself. Doing this regularly doesn’t only contribute to your knowledge, but it also levels the knowledge across the team, because there’s always this one thing that this team member didn’t know about, even though they’ve been around for a while.
Following these steps doesn’t just help you understand the new code you’re working with, it is also the best way to introduce yourself to your new team, learn from and with them and work for them to achieve a higher level of success.
There will be situations where you’ll run into blockers, people that are harder to communicate with, job security issues that might impede you from understanding the system, and in that case the best advice I could give you is to try to find other doors to get to where you want to go.
And if there are no doors, then go ahead and create one. Don’t give up too soon, and know that reviving a dying system will bring you more experience than working with a perfectly designed one.