Table of Contents
Over the course of these articles, I am reflecting on why UI code is much more prone to become legacy, as opposed to other types of software. As I identify the reasons behind this phenomenon, I propose an approach — not the most obvious one, but, as I will do my best to justify, is a key to opening the door to making UIs legacy-proof and scalable and offering extra perks.
- Part 1 — Why does code become legacy?: By using a simple metaphor, I try to illustrate the problem and create a simple reference for the entire series
- Part 2 — Why is UI development legacy-prone?: Another illustration that builds on top of the previous one, further clarifying the problem
- Part 3 — How to make UIs testable and easy to change?: A concise survey of known approaches to UI in the context of the problem, outlined in the previous articles and where they fall short, as well as proposing a new solution
- Part 4 — React as a stateless view in Storybook: Example of what it means to have a completely stateless view
- Part 5 — MVU architecture in a React application: Example of how to make a completely stateless view interactive
- Part 6 — From Figma to React, Vue, Svelte, Preact, and beyond: Exploring the legacy-proof (adaptability) benefits of having a completely separate view that matches designs closely
- Part 7 — Decoupler and the future for legacy-proof UI: Further exploration of perks that this approach allows that go even beyond legacy-proof code considerations
Part 2 — Why is UI development legacy prone?
Why is UI development legacy prone?
Using the line metaphor from the previous article, we arrived at a definition of what legacy code is:
Legacy code — code that is very hard to change without everything going down in flames and that is as costly to refactor as rewrite it from scratch.
This code happens when we have complex and ever-changing constraints and requirements when the correctness feedback loop is delayed, as well as when the codebase grows increasingly large.
And this sounds a lot like what UI development (in general) is. And web UI development is no different. There is probably no other field where requirements change as often as in areas related to UI.
Disclaimer: All of the below examples are contrived, simplified, and only needed for illustration purposes — any semblance to real people is coincidental.
From inception to legacy
Greenfield one-man-gig project
There exist lucky people who start working on a project from scratch. This is the happiest place to be if you are a developer.
As you receive the requirements, the idea behind what needs to be built is generally straightforward, the backlog is fresh and well organized, and designs are in, for the most part.
You begin working on it, setting up the project, hustling a bit with configurations initially, but once you figure that step out, the game is on, and you start building.
As you build your first components, you see quick progress, you don’t need tests, as you are able to navigate the entire application in a couple of clicks. You can see your UI with the help of your dev server or some sandbox environment. Your priority is to fulfill the requirements over making the code last.
With some setbacks (we are living in the real world), you manage to get everything delivered on time and everyone is pretty happy.
It’s much more likely you are going to be in a different situation and be working on somebody else’s greenfield project and not by yourself anymore.
It will be much more difficult to understand the thought process of the person who built the application.
The last person most likely didn’t pay much attention to anything other than the requirements, so little (if any) testing, tightly coupled, and convoluted logic due to cutting corners during development.
As you now receive requirements, it will be mostly guesswork for you how long something will take to make it work.
As you start working on it, you are mostly debugging through code.
You can no longer click through the UI and know where everything is located.
As you develop, you try to avoid modifying the original logic as much as possible. Layer by layer, you tightly couple one feature on top of the other, as you try to understand the original code and get work done by the end of a sprint.
Most likely, you won’t be able to test things properly, as you are already overwhelmed and struggling with requirements and debugging.
Yet, if you are lucky, you start writing tests for your code, however, you probably make them white-box tests, meaning they are tied to implementation as opposed to testing overall logic with inputs and outputs, which would be part of the problem later on.
Layer by layer, the codebase becomes what’s known as legacy code.
It’s most likely, however, that you will be working on a legacy project as a developer.
At this stage, there is almost no hope for refactoring the legacy part.
The feedback loop for most of the applications is going to be delayed.
The process of covering the application with tests will always be lagging behind and draining motivation.
UI development is legacy prone because quick feedback and effective design patterns allowing for modularity aren’t built into the project during the stage when it’s still a green-field project.
However, the purpose of this article series is not to paint a bleak picture but to explore and propose solutions. While it is true that many of our lines of code may not stand the test of time, it is not an inescapable fate. By understanding the root causes and learning from the experiences of countless developers before us, we can anticipate and mitigate these issues.
Stay tuned for Part 3, where we explore ways of how we can make UI development testable and effectively modifiable, taking our first steps towards a more future-proof approach.
To delve deeper into the topics discussed in this article, consider visiting the following resources:
1. Understanding Legacy Code: This website is a rich resource for understanding legacy code and strategies to effectively deal with it. You’ll find a wealth of information that can help you navigate and improve legacy systems.
2. Greenfield vs Brownfield: In this LinkedIn article by Giorgi Bastos, the concepts of greenfield and brownfield projects are explored in detail. Giorgi provides great insight into the differences, advantages, and challenges of both approaches.
3. Greenfield vs Brownfield in Software Development: Synoptek provides a detailed comparison between greenfield and brownfield software development, further enhancing the understanding of these concepts and their implications in UI development.
4. Advantages and Disadvantages of White Box Testing: This page on JavaTpoint gives a balanced view of white box testing, discussing its advantages and limitations in detail.
5. White Box Testing: Pros and Cons: Segue Technologies provides another perspective on white box testing, detailing its pros and cons. This article helps you understand why white box testing can be part of the problem in maintaining UI code.