As you approach a legacy system, there are many things (plays) you might do to get a handle on it. We covered this list on a general level in my first post in this series.
In this post, we are going to cover maybe the most important play: the system review.
What Process Is the Team Following?
What do you do in a system review? The first and perhaps most important thing to realize is that the system is more than just software. It requires people to write/maintain the software, and people need processes.
Before jumping into the code, ask yourself questions about how the team gets from idea to requirements to production. Here are some of the important things to look for when documenting the current process:
- How many developers are actively working on the code?
- Do they have a backlog? If so, where?
- Are they using source control? If so, where?
- Do they have a formal code review process?
- Do they use automated tests as part of the development process?
- Do they have a robust logging solution?
- Do they have a QA environment? (they might have multiple non-production environments)
- How do they deploy to their QA environment?
- Do they have a PROD environment?
- How do they deploy to their PROD environment?
What Is the Current State of the Project?
If you have access to the existing development team, your next stop should be discussing the current state of the project with them. (You will probably have to talk to the team to get your answers to my first question, but here we want to learn what the existing team sees as the system’s problems).
What Are Some of the Project’s Metrics?
This step usually involves pulling down the code and identifying some metrics to measure it. Code metrics are not nearly as useful as actual experience with a code base, but metrics can help target our dives into the existing base to determine where attention needs to be paid.
Metrics such as Code Complexity can be useful in finding potential problem modules/methods. Apps like NDepend (check out my quick review of it) make it easy to quickly pull together common metrics, including Cyclomatic Complexity, lines of code, and more. If I had to pick four big metrics, I would look at:
- Lines of Code
- Lines of Code by Module/Class
- Lines of Code by Method
What Is the State of the Code?
Take a static dive into the code using Visual Studio (or an editor). Look around. Try to build a mental model of the code. Document as you go. Find interesting aspects of the system and note them; this will be useful later. A few aspects to focus on include:
- Dependencies (a tool such as NDepend makes this easier)
- Big methods/modules (lines of code and complexity)
- Unit tests – Assuming they exist
- Security concerns
Be sure to document all of the integrations. What does this solution rely on? What relies on this solution? Keep in mind that integrations are not always obvious. Identifying other systems that depend upon your solution will almost certainly require you to have conversations with existing staff or reading some documentation. Integrations can be particularly tricky, so you should not skip this step. While you’re going through it, ask yourself, “can we mock these integrations for running on our machine?”
Next, take a dynamic dive into the code. For this, I recommend loading the project in something like Visual Studio, building the solution, and running it. Take it through the most basic and happy path to test its functionality. If this is an eCommerce project, you might want to walk through the process of placing an order.
One thing to keep in mind during this step: determine if you can safely run the project on your machine. Do you consume production or QA resources while running? Yep, we’re coming back around to the documented integrations.
Make sure you also document the libraries that this system depends on. This is useful for finding outdated libraries that need to be updated before you take on any work. Again, NDepend can be helpful here. It can generate this in a matrix form for a quick review.
Legacy systems are fun, but getting your bearings straight right from the beginning is crucial.
System Review / Code Review
Design the Ideal End State
Mini Spike Work
Add Some Unit Tests
Determine a Migration Strategy / Strangle
Segment the New from the Old