Modernizing a legacy application is a process of balancing very different teams to a point where new and old coexist in harmony. This is not just a story of balancing technology, but also cultures and philosophies. The modern user experience (UX) designer meets the incumbent design philosophy and well-worn mental models of existing users. The developer culture of the modernization team meets the legacy platform’s ‘business as usual’ (BAU) culture.
Legacy systems can have development teams that have evolved over decades. These teams can have varying levels of experience, operational maturity and discipline. The infrastructure and codebase of legacy systems may have grown in complexity over time, may be brittle, or may have outdated security mechanisms – or all of these things combined.
Maintained legacy systems can often become shells of what they once were; like a grand building showing its age with cracks and a little trouble with the plumbing. Left unmaintained, it may look more like an abandoned highrise with broken windows, the copper piping stripped out, and a crackhouse running on the fifth floor. This state of affairs will directly affect the attitudes and behaviour of BAU teams. When BAU have an aversion to making system changes, you need to dig deeper to understand why – are they the last COBOL programmers that act as high clerics keeping the grand old mansion looking its best day in and out, or are they just avoiding the disgust of rummaging around in the plumbing of the crackhouse? These systemic issues affect regression, release cycle times and team morale.
Recognising the environment you’re working with when modernising an application is essential – the natural reaction to modernisation efforts for a BAU team is fear and resistance – so, the mission for a successful modernisation team should be to answer these three guiding questions:
- How do we take the legacy BAU team on the journey without resistance?
- How do we decouple the new front end from the legacy platform as much as possible?
- How do we make a modern experience for existing users?
How do we take the legacy BAU team on the journey without resistance?
The skills of modernisation are not the same as those of BAU. This does not mean we don’t want to try and take the BAU team on the journey of modernisation, but it does mean we don’t want to hand over the reins. There can be fundamental clashes we need to manage.
The BAU team should be consulted and engaged throughout the UX discovery and redesign cycles, however, it is critically important to navigate the “you can’t do that” and “it doesn’t work that way” moments to find the root cause of resistance from a technical standpoint consistently and iteratively throughout the design and implementation cycles. The key to success here is to have a UX design team with solid software architecture chops so they can dive into the tough conversations as they arise and find good solutions with the BAU team in a collaborative manner.
Throughout the development cycle of integration, there should be ongoing communication and transparency between the modernisation and BAU teams to keep the familiarity up and resistance down as much as possible. It is essential to make sure that a culture of us versus them – on either side – does not manifest during the process, no matter how frustrating things get.
How do we decouple the new front end from the legacy platform as much as possible?
For the new aspects of technology we introduce over the legacy system, we need to instil modern DevOps continuous deployment capabilities and agile development principles using current technologies that have industry acceptance, longevity and strong community support. This change would be excellent to introduce over time to the BAU platform, but this is a journey in itself that may take some time or not be possible at all. The most important thing is to focus on managing regression and instilling release discipline if it does not yet exist.
The key to decoupling the front-end from the back-end is clearly providing an application programming interface (API) over the legacy functionality. The API is essentially a contract between any new systems and the existing service; modern applications expect modern contracts that are provided through the plumbing of the modern web browser using secure hypertext transfer protocol (HTTPS). This is often called representational state transfer (REST) and contracts that follow this protocol and methodology are known as being RESTful.
The problem is, of course, legacy applications and BAU teams are often in no position to be providing a modern API. This is true for a few reasons:
- Designing truly RESTful APIs and mapping legacy data models to a JSON object you would want to process on a modern client is non-trivial. This doesn’t mean all BAU teams can’t do this, it just means you need to be sure that your BAU team can handle it.
- Modern authentication and encryption mechanisms are a huge liability if not correctly implemented – and lots of legacy architectures do not even support them. You don’t want your BAU team rolling their own API security.
- If you want to later change your legacy systems it makes sense to decouple the contract from the legacy system.
To solve for this issue we generally wrap whatever mechanisms the BAU team provide for accessing the logic or data layer of the legacy application with a lightweight purpose-built secure API facade that hides the complexity of the system to modern client applications.
If you have a five-story crackhouse, should you even be trying to integrate a modern application on top? Doesn’t it make more sense to redevelop the core platform? Well, maybe – there are benefits to going through the decoupling process as a short term strategy to allow you to audit the functionality of the existing platform and clearly define the feature set in an API contract so you don’t end up with second-system syndrome where scope creep end up with an over-engineered Frankenstein that never gets done – because, hey – it needs to satisfy the contract before it does anything else.
How do we make a modern experience for existing users?
As the UX redesign team engage with the BAU team, they start to understand the guiding principles that drove the design decisions in the original software architecture and user experience. This is essential as existing users have a well-established mental model of how the existing software works. Think of mental models as a representation of the surrounding world, the relationships between its various parts and a person’s intuitive perception about his or her own acts and their consequences. This mental model of the software could be a major stumbling block for a modernisation effort even if those same users complain about the legacy system!
This does not mean you should put lipstick on the pig and just duplicate the legacy information architecture and user journeys updating the interfaces to blue and fuschia instead of that shade of bile green, rather, it means we need to design an intuitive ‘self-evident’ user experience that sometimes accommodates the long term legacy users with the clues they need to activate old mental models.
There are several strategies for balancing the tension of redesign with legacy mental models. Examples of how this can be done would be:
- Using labels or descriptions with a meaning that is known and defined by the legacy system that represents a similar or the same thing
- Structuring content (information) so that it aligns with the mental model of the legacy system while still staying true to the principle of being self-evident
The moral of the story is that when you have a modernisation project like this, it makes sense to take into account a lot more than just the shiny new toys. It needs a disciplined approach to working with the BAU team, it needs a deeper technical understanding of the existing system, and it takes real empathy with the existing user base to craft an enduring ‘self-evident’ experience.