Why is UI development legacy prone?
Using the line metaphor from the previous article, we arrived at a definition of what legacy code is:
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 correctness feedback loop is delayed, as well as 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 fields related to UI.
From inception to legacy
Green-field one-man-gig project
There exist lucky people who start working on a project from scratch. This is the happies place to be if you are a developer.
As you receive the requirements, the idea behind what needs 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, 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. Your priority is to fulfill the requirements over making code last.
With a bit of setbacks (we’re living in a real world), you manage to get everything delivered on time and everyone’s is pretty happy.
It’s much more likely you are going to be an 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 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 guess work for you how long something will take to make it work.
As you start working on it, you are mostly debugging through code.
As you develop, you try to avoid modifying 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 struggling with requirements and debugging.
Yet, if you’re lucky, you start writing tests for your code, however, you probably make them white-box tests, tied to implementation, that would be part of the problem later on.
Layer by layer, the codebase becomes an epitome of 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 the most of the application is going to be delayed.
The testing of the application 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.
Whether you want it or not, the majority of code you will write will be a throw-away code.
Yet, there are ways to mitigate. Over the course of these articles, I will discuss an approach that I believe is going to prove resilient to this type of problems.