In our first of three blogs drawing from our modernization guide, Accelerating Application Modernization — A Practical Guide, we took up some of the typical modernization approaches on a high level. In this second of three articles we take up several common motions—the typical activities that one has to do when modernizing a large, complex codebase.
Whether it’s a full rewrite of a legacy system, a move to a cloud environment, the containerization of a sub-system, the creation of microservices, the refactoring of hard to maintain code, some activities are common to most types of modernization activities.
Motion 1: Review the "as-is" architecture
Most of the time the existing system architecture is unknown. Even if there is some documentation, it’s either not detailed enough or has fallen behind the implemented reality. Almost always the real “as-is” architecture in practice is not the same as what you might think. This motion is usually a starting point for most of the Action motions, like decoupling components, or even for just planning the new architecture. Hence, you will see reference to this motion built into most of the remaining motions we describe in this section.
Figure 1 – Architecture document vs. the real “as-is” architecture.
Architecture exploration is a part of all the motions described below. It’s part of any work done in the context of large systems. This is probably the most pervasive motion in all application development and especially in maintenance. It is a necessity when doing any kind of modernization of an existing system.
Motion 2: Plan the “go-to” architecture
Unless building something completely greenfield, an architectural diagram should always include existing components, as no system is built in isolation. Typically, this planning process is a step in one of the other, more action-oriented motions of modernization.
For example, as we see in Figure 3, as it relates to identifying candidates for componentization, we have a step at examining the current architecture, followed by planning the “go-to” architecture.
A common approach to building modern systems is establishing a separation of concerns. The idea being that each type of activity (user interface, business logic, data handling) is handled by a specific layer. This helps to modularize and isolate components of a system, creating layers of abstraction and making it more flexible to change. Those layers can be defined in the “go-to” architecture and checked for compliance. This is typically an exercise that involves multiple software architects to bring together an understanding of existing system architecture.
Like others, this motion starts with an understanding of the current architecture, but then gets into understanding the potential “to-be” scenarios and then sorting through these scenarios to agree on the best plan. Also, best in class teams build in a method to ensure the new architecture actually gets implemented by the development teams.
Motion 3: Identify candidates for componentization
The challenge is to look at all the interconnections between components to see where you might have good break points to cluster components. Typically, this is the common motion behind establishing a new microservice within or next to the legacy system. Usually the legacy is a big ball of COBOL or even Java, that has proven to work well over time, housing complex and well-tested business rules, and does not need to be discarded any time in the near future.
The process here is typically to identify a cluster of components in a specific functional area, which can be “cordoned off” into a new layer, API or microservice. Then the impacts of that change need to be assessed and the project can then be estimated and implemented.
The team will typically start with a functional entry point and explore all the components going down the chain of that function. Then look at all the related areas and figure out which components need to also be reviewed to either include inside the new microservice, or to be interfaced to it from the outside. Once the microservice is zoned off, impact analysis takes place to understand what else is dependent on that component.
Motion 4: Identify obsolescence or vulnerabilities
In a system with thousands of components, many of which are already taken from open source, it’s important to keep on top of versions and known vulnerabilities. Older versions of OSS components typically have more known vulnerabilities and can become completely obsolete. Staying on top of this can be an enormous task, and there are a number of tools in the Software Composition Analysis (SCA) space that can help. Once the obsolete components are identified, they need to be replaced or the architecture needs to be altered in order to do without them. Motion 6 discusses replacing or rewriting a component and Motion 7 explains the process of inserting a new framework.
Figure 4 – Results of search for obsolete components.
This motion starts with the output from the SCA tool, identifying the components or frameworks that are affected. Then the real work of assessing the impact and workload of these changes begins.
In our thrilling conclusion, we'll discuss action motions and get into the actual modernization in the codebase.