Building a House

I’m renovating a 1905 house, and true to the Author’s word, it hasn’t fallen down. But it did require foundation repairs, major systems upgrades, and updates. Houses aren’t static, they move, they breath and if you simply build one and never touch it again, it won’t make it past the 100-year mark.

In the software world, we build, test, and iterate quickly. Crafting a house, on the other hand, is a giant waterfall on a waterfall. Before you know where to put your walls, you have to know what kind of couch you want. It sounds like hyperbole, but there’s little room to decide “as you go”. If you find out you want a few inches of toe room for your toilet, it’s hard to tear down your walls and re-route your plumbing, so you better get it right the first time. When it’s finally time to pick light fixtures to give your house the finishing touch and you fall in love with a wall-mounted lights, too bad - all your receptacles are off the ceiling, installed way before drywall, texture, and paint.

The house building process leaves very little room for iteration. Feedback cycles are measured in weeks, sometimes months. Planning everything out and accounting for every use case right from the start is simply impossible. Now, this is true for both building software applications and building houses. But while being stuck with early, poorly informed decisions is a fact of life in house building, it fortunately doesn’t have to be in software.

The Better Way

Encouraging developers to write paragraphs before each method and “figuring out exactly what a method should do…its spec may be a paragraph or even a couple of pages”[1] does not sound like the quickest nor the best way to get feedback. It’s not even the best way to spec out a project.

Code blueprints should be free from implementation details (as much as possible) and give high level feedback on the concept. In my UT on Rails course, I have students write user stories to explain high level concepts behind what a visitor will see and do as they interact with your project. This type of a “blueprint” is a common and easy way to introduce new developers to the design process. It’s not a commitment to implementation or architecture. User stories guide a project, not dictate it. User stories are not waterfall.

I also encourage writing “specifications” which are somewhat different from “blueprints”. Specs in Ruby are tests that can be run against your code to verify it does what you say it will. These are tied to the implementation, which means you should be willing to throw them away when your project scope changes, or if your implementation takes a different direction.

Say “No” to Building Software Like We Build Houses

Every day as I work on my house, I wish it was more like writing software, not the other way around. On one end of the spectrum is coding with no design at all, on the other end we get waterfall. Both extremes are considered harmful. So what should you do?

Don’t bury yourself beneath a mountain of metaphorical bricks before you start a project. Yes, put thought into your work. Yes, make mistakes fail early and often. Yes, change your blueprints to suit new understandings of the problem definition. But please, under no circumstances ever build a piece of software like you would build a house.

Subscribe to my Newsletter 😻 🤠

Keep Reading 🚀

Today I have an unusual proposition for you. I’m spending a bunch of time to try to get Beto elected to Texas Senate, so I’ve not been able to write as much technical content. Rather than slow down on my door knocking, I’m looking to pick up the pace, and I want you to do it with me. Starting today, I’m offering anyone who phone banks or “block walks” (knocks on doors) the opportunity to win some of my technical time. Here’s how it’s going to work.

You might know rubocop as the linter that helps enforce your code styles, but did you know you can use it to make your code faster? In this post, we’ll look at static performance analysis and then at the end there’s a video of me live coding a PR that introduces a new performance cop to rubocop.

Rails 5.2 was just released last month with a major new feature: Active Storage. Active Storage provides file uploads and attachments for Active Record models with a variety of backing services (like AWS S3). While libraries like Paperclip exist to do similar work, this is the first time that such a feature has been shipped with Rails. At Heroku, we consider cloud storage a best practice, so we’ve ensured that it works on our platform. In this post, we’ll share how we prepared for the release of Rails 5.2, and how you can deploy an app today using the new Active Storage functionality.