What Renovating My Home Taught Me About Application Architecture
In This Article
Recently I embarked on a new challenge: renovating my entire house, starting with the bathroom. During this process, I both made a lot of mistakes and also fixed a lot of mistakes from the previous builder. Going through this process it dawned on me that doing renovations, or the structure of a house in general, has a ton in common with application programming and design.
I found myself committing many mistakes that I often warn newer developers about. I also noticed many of the same sort of mistakes that the previous builder made that we see in many codebases.
The purpose of this article isn't just to show that renovating and programming are similar but to try and make the process of programming more concrete so we can more easily see the pitfalls and purposes of good design. One of the difficulties of designing and building an application is that we cannot touch and feel the product. Any positives or negatives in the design or the process is felt more in the abstract. One of the nice things about building with physical products is that success and failures are really felt because you are dealing with physical objects. Hopefully, this will become clearer as you read on and I step through the issues I dealt with as I renovated my bathroom.
This will be a multi-part series of articles. Starting with electrical wiring then discussing drywall, demolition, framing, plumbing, tile and finally, paint and trim.
On the surface electrical is fairly simple, but if done incorrectly, could have a huge impact. Basic home electrical is all about creating a loop that delivers power. You start with your power source, the breaker box. Inside the breaker box is, you guessed it, breakers. These breakers provide protection against too much load and determine the number of amps that will be delivered through the "power loop."
In my case, I was using 20 amp breakers so I needed 12 gauge wire. The wires used are typically Romex. Romex today is almost always copper and has at least one black wire, one white wire and one ground wire. There are more variations, but this is what I needed for this job. The black wire is your "hot" wire. It delivers power. The white wire is usually your return wire (in the most basic setup). The ground is there for protection so the power has somewhere to travel in the case of a short.
One of the many reasons we are renovating our house is the wiring. The first issue is that our house has aluminum wiring! For those of you that don't know, there was a 4- to 5-year span in the late 60s/early 70s where builders used aluminum wiring instead of copper wire. They did this because at the time, copper wiring price was high.
The problem with aluminum wiring is that it is not as good of a conductor, meaning you need a larger gauge for the same amps if you were using copper, and it doesn't mix well with copper. If you just connect an aluminum wire to a copper wire, it will slowly corrode and can catch fire. There is a way to avoid this though. You need to use a special connection paste that is anti-corrosion. That of course requires that you are aware of this problem and what special type of paste you need to use. Many people out there are not going to know of this requirement, and it is not very intuitive that this is needed.
The second issue is the layout and connection of our wiring. Currently, all the wires start at the breaker box in the basement. Then most of them go straight up into the attic. This isn't a terrible design, just not as convenient as if all the wiring was in the basement. Once you get into the attic, the problems begin. Normally, you would have a wire that supplies power to a specific room and use case. Imagine one wire delivers all the power to the bathroom outlets.
In my house, this is not the case. Once you get into the attic, all the wires delivering power were basically used as agnostic power delivery sources. So instead of connecting one room use case to one power source, each individual switch or receptacle was randomly attached to the most convenient (for the builder, not the homeowner) power source. The result is that one power source serves many different ends throughout the house.
Why is this an issue? Imagine you needed to change an outlet in the kitchen. The first step is to kill the power to that outlet. But instead of all the outlets in the kitchen going down, the power to your son's bedroom light, an outlet in the living room and the bathroom fan all go down. Can you see how this design might not be desirable?
The fix was to drag all new wiring. I had to start from scratch. First buying all new wiring and breakers. Then creating the path for the new wires in the basement up to the appropriate endpoints. One power source for the outlets and one for the lights and fan. Making sure to follow all of the codes and conventions so that the next person will get exactly what they expect.
The second step was to remove all of the old wiring. This was, of course, a little difficult as various endpoints throughout the room had different power sources. And I found out after I ripped out one of the wires that I thought was delivering power to a light, was in fact providing power to the fan in the other bathroom! So the "refactor" of the power sources took much longer than it should have.
The wheels are probably already starting to turn in your head about how this connects to application development and how you have probably seen very similar problems in the codebases you have worked on. In most applications, our "power" is the data. The data flows from somewhere offsite that we have to connect to and distribute throughout the application. When we are building out the "wires" that connect our data throughout our application, we need to be thinking not only about just getting the data but how we are getting the data.
How is the data distributed? What happens when we want to add another view to our application, is it easy to plug into the current pipelines? What about when we need to switch out the data source or replace the view? Will this be an easy task, or will we have to go into the "attic" of the application and start pulling "wires" until we have the result we need?
Both the home wiring and the electrical wiring is the unseen powerhouse of the job. When done correctly, every other step is made easier and no one else has to think about it -- it just works. They are both one of the first steps you take in your project, and they both share many of the same pitfalls. And finally, neither should be taken lightly.
When you sit down to start planning your application -- yes, planning not just coding -- you need to be thinking about how the data flows. Just like in the electrical wiring, you do not want to just extend wires and have people connect to them "willy nilly." This is one of the most crucial aspects of application development as it is the backbone. You need to plan assuming that at some point other people are going to be making changes. Think about what they would expect when they open up your code. Some of the aspects you should be thinking about are:
- How is your view going to be updated (state management)?
- How is your data going to be updated?
- Unidirectional data flow.
- How are you going to allow for plug and play changes?
- How are you keeping your code separate and avoid coupling?
- Does your data need to be real-time or does it stay mostly consistent?
You want to make sure that what you chose above stays consistent. If you are using streams in one part of the application, then you should use streams in all parts. If you are using some sort of Redux system, then use it throughout as well. Make sure that when someone pulls the "wire" from one view that only that view is affected.
In other words, plug your view directly into one source of truth. Do not just "pick up" that data from somewhere else because it was "there already." You do not want to make future developers (it might even be you!) have to follow all the way back to the power source to make sure ripping out the code doesn't accidentally cut off the data to other parts of the application.
That's all for now about wiring. The next article will discuss the demolition phase of the project (hint: think refactoring).