Hero Dev

You are writing legacy code

March 18, 2020

Technology is constantly evolving, and that makes the code we write today the one we are going to rewrite tomorrow.

-Saskatoon Dev Talks, Feb 27th 2020-

If you worked with frontend for some time, probably you have worked with many different technologies (server render web app, plain Javascript, JQuery, React, Angular, Vue) or a mix of them for doing the same thing: render a web page.

We need to keep in mind that technology is in continuous evolution.

Let’s take a look at how the way we use to build software might change throughout the years.

A tale of one startup

No one wants to start a new business or project with old or deprecated technology, and everybody tries to choose current bleeding edge technologies that the team knows how to use.

Let’s say that we are building our new startup back in 2005. Our app does a lot of cool things. One of them is to show a list of heroes that looks like this:

Heroes list

Server rendering

At that time, PHP was the technology to build your website with. We can render our pages on the server easily, so this is our choice to start our new promising project.

Considering $heroes is coming from a database, the following code is iterating on them and generating the output as HTML that is going to be returned to the browser.

<ul>
<?php foreach ($heroes as $hero): ?>
   <li><?= $hero->name ?></li>
<?php endforeach; ?>
</ul>

Now we have our server-rendered app working fine in production. Sweet!

JQuery

However, as time goes, we wanted more flexibility on the frontend side, so we looked around and found out that jQuery is booming, and it fits our needs. So, here we go to rewrite our amazing app to use jQuery:

<ul id="heroes-list"></ul>
<script>
   $(document).ready(function() {
      $.get("heroes.json", function(heroes, status) {
         heroes.forEach(hero =>
            $("#heroes-list").append("<li>" + hero + "</li>")
         );
      });
   });
</script>

Edit JQuery Ajax

The code above is getting the data from the server (imagine heroes.json as a Rest API) and appending each hero to the DOM inside the heroes-list div.

React

As our product grows, our team grows as well and we realize that jQuery doesn’t scale very well. Adding routes, for example, requires a lot of effort as well as maintaining the code-base and adding new functionality. But if we look around we see that there is a lot of new hip frameworks floating around. Angular, Vue, React, all of them offer great flexibility when working with frontend and make it easier for us to scale our app as there is a ton of libraries we can just add to our project in case we need something.

Here we go to rewrite our application to React:

import React, { Component } from "react"
import { fetchHeroes } from "./api"
import "./styles.css"

class App extends Component {
  constructor() {
    super()
    this.state = {
      heroes: [],
    }
  }

  componentDidMount() {
    fetchHeroes().then(data => {
      this.setState({
        heroes: data,
      })
    })
  }

  render() {
    return (
      <div className="App">
        <ul>
          {this.state.heroes.map(hero => (
            <li key={hero}>{hero}</li>
          ))}
        </ul>
      </div>
    )
  }
}
export default App

Edit React Fetch Heroes - full lifecycle

The code above fetches the data from the server once the component was loaded and renders the list.

Sometime later, hooks feature was added to React, improving the way our apps are written a lot. We started using it, and soon we updated our hero list to use hooks:

import React, { useState, useEffect } from "react"
import { fetchHeroes } from "./api"
import "./styles.css"

const App = () => {
  const [heroes, setHeroes] = useState([])

  useEffect(() => {
    fetchHeroes().then(data => setHeroes(data))
  }, [setHeroes])

  return (
    <div className="App">
      <ul>
        {heroes.map(hero => (
          <li key={hero}>{hero}</li>
        ))}
      </ul>
    </div>
  )
}
export default App

Edit React Fetch Heroes

In our startup case study, we are always rewriting to something newer as the time goes. The last one is written in React, but we don’t certainly know what is going to take place in the coming years, maybe Svelte, or Polymer or maybe Web Assembly? Who knows.

What is Legacy Code

All the examples above render just a simple list of heroes, but in practice, it could be much bigger with a lot of functionalities and features. That means changing technology or approach can take a lot of time and planning.

As we can see with this simple startup tale, we are always writing code that, somehow, is going to be rewritten later. I think that we can safely assume the following:

A code becomes LEGACY CODE as soon as shipped into production!

Dealing with technology changes

There are three possible ways of dealing with a huge technology change, for example from a server-rendered app to a React App:

Keep maintaining/adding features the existing one

If your app isn’t that big and improving the app and adding features is not an issue with the current stack, chances are that you don’t need to change the stack you are using currently.

Rewrite it from scratch

Rewriting from scratch means you will throw away your current app and replace it with the new one. If your app is a small one and you can keep maintaining the current one while rewriting the new version, this could be a good approach for you.

But if your app is large, or it has years of knowledge applied throughout code, I wouldn’t recommend doing this.

Progressively rewrite

This approach means you are going to keep the current app, progressively moving towards the new approach. For example, you can start moving one page to React while all the others still use the old tech, gradually moving towards a single page application (SPA).

It’s likely that this is the option you will choose if your app is a large one.

Leaving behind a good legacy code

As we just saw, we are writing legacy code all the time! It does not matter if we are using the cutting edge technology of the moment, it is going to become legacy code as soon as shipped into production.

With that in mind, what really matters is leaving behind a good code, so ourselves or our coworkers can look back and understand what is going on.

There is just one rule to rule everything, and it is called KISS:

KISS - Keep It Simple Stupid

Keeping it simple can be hard, though. It is not the scope of this article to cover how to keep your code simple, as this could take a whole new blog post, but simple actions can help your code to be clear, for example:

The main point is:

Any fool can write code that a computer can understand. Good programmers write code that humans can understand

- Martin Fowler


Alex Andrade

Personal blog by Alex Andrade.
Saving the day with code.