Last year, we spent a significant part of the fall and early winter renovating some aspects of our apartment*. Things like (finally) updating the flooring in the living room, updating the wallpapers, painting the interior staircase white, and changing out all doors. The renovation process provides some interesting analogies to the process or updating an existing software code base – especially in discovering the design decisions of the past and unearthing the layers of legacy that underlies why things look like they do today.
Our apartment is not all that old (by European standards at least), having been built in the 1980s. Still, there have been some changes made over the years. It would have been very helpful if previous owners had documented the changes that they made. Instead, the renovation turned into a bit of archeology, as the work unearthed the accumulated updates and modifications.
The first discovery was that in one room, the concrete underneath the wooden floor had never been properly smoothed out… instead, there was an uneven and rough surface that had clearly be put in quickly and then covered over with some padding and the wooden floor. In particular, a piece of a reinforcement steel bar poked out of the floor, making it impossible to put in new floorboards. Which makes no sense, until we saw that the old floor had some carve-outs on the bottom side that neatly made room for the metal bar. Not exactly the most principled solution. We took an angle grinder to the steel bar and removed it, leaving the floor nice and flat for future updates.
It also became apparent as we worked that many of the walls were not quite as straight as they seemed. Most of the building is concrete, which means that “adjusting” the walls is really not feasible. Thus, we just had to live with the not-quite-straight-angles were walls met and walls that bulge slightly or are even taper as they go along… The kind of little details that you never notice until you lay a floor that follows the walls or have to put up new trim around a doorway.
Maybe the most interesting case was the middle of the living room floor. What is now a single room used to be two separate rooms (many of the similar apartments still have two rooms), but over the years the wall has been removed. From the evidence, it looks like someone first opened up a doorway in the middle of the wall. The hole in the concrete floor underneath the door opening was filled in, and the doorway itself was patched with some wood that at least looked similar to the floors surrounding it. At a later date the rest of the wall was removed. This time, instead of patching the wooden floor, whoever did this just left a hole and glued a threshold board on top of the floor across the entire room. Simple and expedient in the sense that there was no visible gap left. However, it had the side-effect of making the room clearly look like a combination of two parts, as well as providing an complication for the placement of the furniture.
We ended up fixing quite a few of these accumulated issues in the apartment… the above are just a few examples.
Another lesson is that it is hard to stop once you have started renovating. It just keeps snowballing. Tearing up the floor require removing the skirting, which in turn leads to a close look at the wallpaper. And the skirting brings with it the trim around the doorways. Then you notice that the old doors do look a bit yellowed compared to the nice new white wood… and suddenly the project has grown from just replacing the floor to a total floor-to-ceiling renovation. The only place where it makes aesthetic sense to stop is between distinct rooms – where the doorways provide a natural stopping point.
So what, software?
The home renovation process has a clear software analogy in software renovations.
Motivation. Typically, a long-lived software package works OK. As a user of a command line, a GUI, an API, or programming framework you learn to live with idiosyncrasies (like the threshold glued in across the living room floor) and usually never question what lies beneath the surface. There might be some strange patterns (like not-really-straight walls), but it is doing the job overall. However, at some point, it starts to feel just a bit dated. It might be aesthetics, it might be the need to adjust to new technologies, it might be that there are some really good new ideas coming into the team. A tipping point is reached and it is time to get going, it is time to scratch the itch.
Here, different teams and different products have very different levels of sensitivity. For some consumer-facing web site, constant renovation to stay hip might be de-rigeur (just like some people just have to keep updating their homes to the latest greatest fad). While for a business-to-business system, ten-year-guaranteed stability trumps everything and change is bad as a matter of principle.
Snowballing. The snowball effect is very real in software. Start making a change in one place, and you realize that it would be so much nicer if you just change this other thing… it might something as small as refactoring and renaming functions in a single module, or something as large as redesigning a major API. In a GUI, it is very easy to find it very hard to stop – after all, inconsistencies in the look and behavior of a GUI can be obvious and annoying, even if the functionality is essentially the same.
Modularity. The key to stopping the snowball is to have places where it is possible to stop. This comes down to having clear delineations between modules – where it is possible to change in one module without necessarily changing another one. In the end, the goal is to have something that ships. Just look at how Windows 10 carried along the old Windows control panel for a long time. It was a naturally encapsulated subsystem that could be updated later separately from the rest of the operating system. It looked a bit weird to go from the new style of the top-level GUI to the older-looking panel. But it worked, and eventually the control panel got updated as well. Just like you can renovate a house room by room.
Accept imperfection. When it comes to renovations, in the end, you want something that looks and works better than before. But unless you tear everything down and start over, the result won’t be perfectly designed, elegant, and 100% consistent. Not everything will be updated, and the old top-level structure will typically still be there.
Pride. Accepting imperfection does not mean letting standards slip. Software developers are the craftsmen of the modern age and should take pride in the work and have a sense of basic standards that should never be let to slip. Look at the project, code, product, interface, or whatever it is with the eyes of an outsider – what would they say about it? Don’t get all home-blind, take a critical look at your own work. Doing things to an appropriate standard from the very beginning is cheaper in the long run, as tends to avoid rework down the line. This is not something you necessarily get from (supposedly) professional builders.
ugly inevitable joints. There will be strange join points and weird inconsistencies between different parts of a program or software system. This often OK, and can be hidden behind the software analogy of trim and skirting – a higher-level framework, wrapper function, or proxy module can often provide a nicer and more pleasing end-user or programmer interface.
Document! When building or changing anything, be a building or a software system, document what was done! Even better, document why things were done and why they were done in a particular way. This will help in two or five or fifty year’s time when it is time for the next major renovation. In software, this kind of documentation is often severely lacking, leading to the phenomenon of legacy code that nobody dares touch since it is impossible to understand just what it does and how. Understanding the history of a piece of software is also very helpful to understand its overarching architecture and design principles. Looking at something without historical insight is rather hard – software is in a constant dialog with its environment, and things typically look like they do for some reason.
Celebrate the archeology. When renovating old software, it is very likely that convoluted, oddball, contorted, and downright fun snippets of code will be found. It is worth preserving such nuggets for the future, as they can be both entertaining and educational for current and future developers. Indeed, that is how you build a culture and tradition around the software. “Remember when J Random Hacker coded this quick-fix thing that the customer discovered and…”.
Allow for future change. Assume that there will be the need for changes and renovations in the future, and build in some allowance for that. In a physical building, don’t glue everything together but use techniques that allow for pieces to be removed and reinstalled again in case some small fix is needed. Screws are generally better than nails. Don’t fill in the screw heads with paint. In software, keep things modular and make sure the individual components are easy to replace without affecting other components.
Writing this blog forced some research into the precise English terms for various parts of buildings. Not being a craftsman, it is not exactly common to talk even in Swedish about the bits of wood you apply for different purposes. Translating it becomes a research project.
Another hard-to-translate concept is just precisely the type of house/home/building me and my family live in. It is an attached row house, and our little row of houses is in turn part of an apartment complex. Saying row house invokes pictures of long lines of identical houses… which is not at all the case here where different parts of the same building vary in height. This kind of mixed architecture was pretty common in the 1980s, and might be coming back again as cities densify but builders still want to offer some people a house-like experience.
“Apartment” might invoke “rental” for some people, but that is not the case here. We own our home, and therefore it makes perfect sense to do internal renovations. Well, ownership of a peculiar kind. Since this is a bostadsrättsförening, which a totally unique construction that only exists in Sweden. Technically, the whole complex is owned by a legal entity that is a basically an association of the people living here. You buy the right to reside in an apartment, not a part of the building per se. The association is responsible for the “outside” of the building and common areas. We are responsible for the inside (there are more precise definitions of the boundary, of course).