BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage Articles Chipping Away at the Monolith: Applying MVPs and MVAs to Legacy Applications

Chipping Away at the Monolith: Applying MVPs and MVAs to Legacy Applications

Bookmarks

Key Takeaways

  • The concepts of MVP and MVA don’t apply just to new applications; they provide a new and innovative way to look at scoping changes to legacy systems that prevents taking on too much change, too soon - see Figure 1.
  • MVAs can help an organization evaluate and refresh its technology standards by showing how a new technology is truly essential to supporting an MVP. 
  • Creating an MVA can help a team evaluate which parts of a legacy system need to be modernized now, and which parts can wait.
  • Legacy applications, because they are often mission-critical, need special focus on sustainability.
  • Finally, it’s useful to keep in mind that today’s legacy applications were, in many cases, shiny and new not very many years ago. Considering an MVA as a part of every new release helps to keep applications fresh.

Legacy applications are often stuck in the slow lane: aging and brittle, poorly understood and barely supported, and based on aging technologies, they are often the last applications to benefit from modern concepts like continuous delivery. Yet because of their potential instability, they are actually the applications that benefit most from concepts like a Minimum Viable Product (MVP) and its related Minimum Viable Architecture (MVA). 

How can this be true? Most legacy applications are relatively monolithic and defy being released incrementally.

Once you realize that every release is an experiment in value in which the release either improves the value that customers experience or doesn’t, you realize that every release, even one of a legacy application, can be thought of in terms of an MVP. Each release is really an MVP that relates to the added value that you are looking to deliver. Therefore each release also has an MVA. Concepts like MVP and MVA provide teams with a laser focus on what is absolutely necessary to test their hypotheses about what changes customers will really value. 

Since the MVP concept is most often associated with new products, it might be better to think of each new release of an existing application as a minimum viable increment, or the minimum set of changes that the team thinks will result in an improvement in the value that customers experience. But since the term MVP already has currency, we’ll continue using it.

As we noted in prior articles, an MVA is the minimum amount of architecture needed to ensure that the MVP satisfies its Quality Attribute Requirements or QARs. Since architecture, for us, is primarily about technical decisions, the MVA for a legacy application release represents the minimum set of application changes that the team needs to make to ensure that the release supports its QARs.  

The release-readiness MVP criteria are typically focused on whether the release will let the team test its understanding of the desired outcomes for customers; MVPs are not "technical proofs of concept". Similarly, the release readiness of the MVA can be determined by evaluating whether the changes being made to the legacy application will ensure that the release will be able to meet the QARs for the application and, in so doing, sustainably meet customer needs.

Figure 1: MVP & MVA provide a "lens" to look at legacy systems in a new way

Process Challenges:
One of the criteria for any release, and especially applications on which the organization depends, is that the application will have passed a set of tests (ideally automated) that validate that the release candidate satisfies its QARs. Running manual tests to evaluate QARs is too cumbersome and error-prone to be reliable. The lack of automated tests to determine whether a release meets its functional requirements and QARs is one of the factors that prevent organizations from delivering value in small increments.

Other factors sometimes prevent organizations from releasing in small increments, leading them to release changes in relatively large, complicated increments. These include:

  • Lack of effective build, test, and release automation. When significant portions of the delivery pipeline are manual, the delays and mistakes introduced by manual steps prevent the organization from doing anything quickly. Even when portions are automated, delays introduced by hand-offs between teams slow things down. Solutions to these problems abound, but they require the organization to change the way it works and sometimes the way it is structured.
  • Tight coupling between applications. When applications share data or components, changes to one can necessitate re-releasing the other. Organizations with tightly coupled legacy applications can find it hard to make small changes because they cannot afford the time or effort to re-release all the applications that might need to be released.
  • Cumbersome release approval processes. Because many legacy applications have become, in a sense, business-critical, approval to change them is often needed from senior business executives who may not really understand the technical issues related to the change. When they need to feel comfortable about the scope and risk of the change, the time and effort needed to translate the changes into common terminology can be substantial.
  • Regulatory constraints. Organizations in regulated industries may have to obtain regulatory approval to release new products, or to change existing products in significant ways. They also need to provide regulatory reporting on the use of these products by their customers. They struggle with being able to make use of the MVP concept because regulators generally want to understand every aspect of the new product or the changed product. The whole reason to use an MVP is to answer key questions with real customer experience data, so the organization is caught in a kind of Catch-22; they cannot release a product to test the MVP, but they cannot fully define the new product (or changed product) without experience. These companies seem doomed by regulatory constraints to have to potentially over-invest in products that customers don’t need because they cannot test ideas early and incrementally.
  • Shortage (or loss) of expertise. In some cases, organizations no longer really understand the legacy application business logic or the technologies on which the applications are based. One solution to this problem is to incrementally replace the parts of the legacy application that are still relevant with more effective modern solutions, working a customer outcome at a time. In doing so, the organization can find that much of the legacy application is no longer relevant or needed, but it takes time to work this out, and in the short run, the organization is left with an even more fragmented solution that risks never being fully fixed because other challenges always seem to come up.

With the exception of regulatory constraints, these can all be fixed but they take time and concerted effort. 

The dilemma of paying down technical debt

Paying down debt, when you have a chance, sounds like a good thing, right? 

Organizations are sometimes tempted to do extra technical work, to modernize, or reduce their technical debt because, as they may rationalize, "we’re going to be working on that part of the application anyway, so we should clean things up while we are there." While well-intentioned, this is almost always a bad decision that results in unnecessary cost and delay because once started, it’s very hard to decide to stop. 

This is where the concept of the MVA pays dividends: it gives everyone a way to decide what changes must be made, and which changes should not be made, at least not yet. If a change is necessary to deliver the desired customer outcome for a release, then it’s part of the MVA, otherwise, it’s out. 

Sometimes, a team may look at the changes needed to an application and decide, considering the state of the code, that a complete rewrite is in order. The MVA concept, applied to legacy applications, helps to temper that by questioning whether the changes are really necessary to produce the incremental improvements in customer outcomes that are desired. 

The application may, indeed, be too far gone to be extended but, in our experience, "total rewrites" almost never succeed either (we’ve never seen, or even heard, of one of these projects actually delivering anything.) If you’re really going back to the drawing board, don’t rewrite the existing system; instead, start from the customer’s desired outcomes and look for different ways to deliver them.

Viability and release scope

The MVA has an effect on the MVP, especially for legacy applications. Both MVA and MVP include an important word: viability. If in evaluating the changes that the team needs to make to the application in order to deliver the MVP, they determine that it is too expensive to achieve the MVP in a sustainable way, the MVP needs to be reconsidered and potentially changed.   

Leveraging the MVA Approach: Using QARs

The Minimum Viable Architecture ("MVA") approach (see our article "A Minimum Viable Product Needs a Minimum Viable Architecture") provides you with a way to decide how much modernization is "good enough" in order to deliver an MVP. Creating an MVA as part of an MVP delivery effort helps you evaluate the technical viability and to provide a stable foundation for the product that can be adapted as the product evolves. Making the MVA architectural decisions transparent helps the organization better understand why certain choices have been made, which helps them make better decisions about how they can adapt the product to changing market conditions and evolving customer needs. 

QARs drive your decisions: The most important MVA architectural decisions that you need to make may be to select the minimum amount of architecture components enabling the MVP to handle QARs that are associated with product/system characteristics such as: 

  • Concurrency—relating to the number of concurrent users, sensors, and other devices that create events to which the product must respond.
  • Throughput—relating to the volume of transactions or data that the product must be able to process over a defined time period.
  • Latency and responsiveness—relating to how quickly the product must respond to events.
  • Scalability—relating to the ability of a system to handle an increased workload by increasing the cost of the system, generally in a near-linear relationship.
  • Persistency—relating to the throughput and structure (or lack thereof) of data that must be stored and retrieved by the product. Often includes decisions about different kinds of data storage technologies (e.g. SQL DBMS, NoSQL DBMS, etc.).
  • Security—relating to how the product will protect itself from unauthorized use or access to product data, by achieving confidentiality, integrity, and availability.
  • Monitoring—relating to how the product will be instrumented so that the people who support the product can understand when the product starts to fail to meet QARs and prevent critical system issues. 
  • Platform—relating to how the product will meet QARs related to system resource constraints such as memory, storage, event signaling, etc. For example, real-time and embedded products (such as a digital watch, or an automatic braking system) have quite different constraints than cloud-based information systems. 
  • User interface—relating to decisions made about how the product will communicate with users; for example, virtual reality interfaces have quite different QARs than 2-dimensional graphical user interfaces, which have quite different QARs than command-line interfaces. These decisions may affect other QARs noted above. (GUI, VR, command line, or other kinds of interfaces.)

For example, let’s assume that you are planning to build a mobile app to support the launch of a product in a new market, using open-source or commercial frameworks that help you to quickly deliver an MVP while creating a new interface to legacy system data. In doing so, the legacy application will inevitably be subjected to workloads that it was not designed to handle. Will those increased workloads cause the legacy system to fail? Will the additional workloads threaten the ability of the legacy system to satisfy its QARs for existing users? Does the mobile application change the QARs for the legacy system? 

Inevitably, new applications that access data from legacy systems will change the QARs of the legacy system by changing workload, throughput, responsiveness, and security-related requirements, among others. Legacy systems were not built to support the needs of the users of new applications, and those needs must be taken into account when deciding how much and where to modify legacy systems. In some cases, no amount of work will enable the legacy system to meet the new QARs, and in those cases, the legacy system will have to be replaced in order to enable the new applications.

Empiricism is a powerful tool for evaluating these questions, and each release of the new mobile application will, at the very least, create an opportunity to assess whether the architecture of the legacy system can support the new demands being made on it. It is likely that the development team will need to modify the legacy application to meet the new QARs. Considering the legacy application changes as part of an MVA for the mobile application will help the team decide how much change to undertake to accomplish the goals of the mobile application’s MVP release.

QARs are a very useful tool for diagnosing areas for potential improvement in a legacy system. Focusing on QARs can help you limit the scope of the change to only what is minimally needed, right now in order to support the MVP. This helps to prevent sliding down the slippery slope to a "total rewrite", which is expensive, time-consuming, prone to failure, and often unnecessary for the MVP.

Limit the scope of the new functionality: Resist the temptation to go beyond the scope of the MVP and turn this effort into a much larger one by including "nice to have" features that are unnecessary for the MVP. Domain-driven design (DDD), which is an extremely powerful approach to software development, is a very efficient technique for identifying the scope of the new functionality that needs to be implemented in support of the MVP and limiting it to precisely what is needed. 

Try to decouple and simplify system components. One of the challenges in working with legacy systems is that they lack modularity, many of them having been written at a time when modular code was not encouraged and most code reuse happened through "copy and paste." While it is tempting to refactor all of this redundant code, stay within the bounds of what you need to do to support the MVP. When you do need to refactor or replace code, make the new code modular and reusable. Microservices play well here as well as serverless functions in some cases. Replace code with calls to shared components or services in the applications you need to change, but also make notes for other applications that may have similar opportunities. That way, when other teams have to modify their applications to use similar services, they will have a bit of a head start. 

Start shifting new work away from legacy systems. Unless it is dramatically simpler and more sustainable to implement new capabilities in the legacy system, develop new business capabilities associated with the MVP with modern technology, such as cloud-based services. If the new functionality has to be initiated from an older program, write a new component or service for the new work and just call it from the old code. Over time, the decoupling work mentioned above plus moving new code to modern technologies will shrink the amount of legacy code you need to worry about.

Using patterns such as the "strangler pattern", or the "branch by abstraction" pattern, as well as implementing a gateway to route requests to the new MVA components when applicable may be helpful for this migration. Keep in mind that all approaches and tools have limitations. For example, using the "strangler pattern" is appropriate for migrating well-defined functionality chunks from a single application, but may not be the right approach if you need to replace broken infrastructure that affects dozens of applications. 

Start identifying "dead code" and opportunistically eliminate it. Use static and dynamic code analysis tools to find out what parts of the legacy system aren’t used anymore, within the scope of the MVA. Target dead code for elimination (but don’t jump right in just yet - beware of scope creep). This can extend to reports - old systems produce a lot of them, and some (or many) may not be useful to anyone anymore; the business may have changed while the system did not. Identifying code that is no longer useful can help a team more easily see whether that code would impact the MVA. The less code you deploy, the more reliable the rest of the code, and the lighter the system use of critical system resources.  Even if the team decides not to eliminate the code, they should identify the potential for removal of dead code to help other teams with their future decisions. 

Organizational technology standards perpetuate legacy systems. Organizational technology standards are useful to prevent unsupportable configurations and combinations of infrastructural technologies from multiplying, but if retained too long they can keep an organization rooted in the past, unable to adapt to the future. Using the MVA concept can help an organization understand whether a new technology is truly needed to enable a team to deliver a particular MVP.  With the proof that the MVA provides, an organization can decide whether the MVP is truly strategic and therefore a change in the technology standards is warranted.

Where should you store MVA data? One of the key MVA decisions is to choose a data store for the data associated with the MVP. Some of this data is likely to already exist in a legacy data store, and in most cases, additional data will need to be captured and stored. That data can either be incorporated into a legacy data store, or a new, more modern DBMS can be implemented to store the new data. The first approach simplifies data aggregation and reporting, at the cost of expanding the use of a technology that may be slated for retirement - for example, IMS/DB. It may be appropriate if a small percentage of the existing MVA legacy data needs to be added to support the MVP. The second approach constrains the use of legacy data stores, at the cost of complicating data aggregation, and should be considered if a large percentage of the existing MVA legacy data needs to be added. A variant of the second approach would be to migrate the existing MVA legacy data to the new DBMS. However, migrating data is much harder than migrating functionality, as that data may be used by multiple legacy applications out of the scope of the MVA. Attempting to do this could result in work beyond the MVA scope.

Conclusion

Legacy systems are a bit like an ancient city that is still a thriving metropolis: their mixture of old and new make it difficult to keep up on needed repairs, let alone substantial renovations to adapt them to rapidly changing needs. But finding a way to continuously adapt legacy systems is essential to evolving the enterprise to a changing world. 

The concepts of MVP and MVA don’t apply just to new applications; they provide a new and innovative way to look at scoping changes to legacy systems that prevents taking on too much change, too soon. In reality, every new application becomes a kind of "legacy application" after its first major release, and finding ways to limit the scope of change is important as applications evolve.

The MVA approach can help an organization evaluate and amend its technology standards by showing how a new technology is truly essential to supporting an MVP. It allows you to challenge technology standards with real data, rather than with just preferences and opinions. 

The process of creating an MVA can help a team to evaluate which parts of a legacy system need to be modernized now, and which parts can wait. Organizations have spent huge sums on failed "total rewrite" modernizations that were, in hindsight, unnecessary. Identifying what parts must be modernized now, and what parts can wait is useful, for it gives an organization a better understanding of their technical debt, while also providing them with a much-needed filter to prevent needless work. 

Legacy applications, because they are often mission-critical, need special focus on sustainability. In fact, fear of making the legacy application unstable prevents many organizations from making important and needed incremental improvements to them, making them even more brittle and risk-laden. Focusing on sustainability QARs, including growing the skills that teams need to evolve the applications, helps to make the applications more resilient over time. 

Finally, it’s useful to keep in mind that today’s "legacy" applications were, in many cases, shiny and brand new not very many years ago. These aren’t just applications written 40 years ago; they are also applications written just 10 years ago, or even more recently. As soon as an application is no longer being continuously updated, it starts to decay. Considering an MVA as a part of every new release helps to keep applications fresh.

About the Authors

Rate this Article

Adoption
Style

BT