Chesterton’s Fence

Chesteron’s fence is a principle that, in essence, states the following:

Never take down a fence until you understand why it was put up in the first place.

Apologies to G.K. Chesterton, who put it so much more eloquently in The Thing (the book, not the movie).

This principle manifests itself in our codebases all the time.

Ever try to delete code you thought was unused? Ever bring down production doing so? I have.

Ever refactor code without tests around it (or even with characterization tests around it) and realize later that you missed a code path? I have.

Ever change a setting in a database, only to realize the system depends on that setting, even though it was marked as unused? I have.

All of these are Chesterton’s fence examples. Put simply, it’s really easy, and almost certain, for us to not understand the system once it’s released into the wild. It grows on its own, adapting to changing circumstances, and a lot of times those circumstances make the code look sort of like this:

Any time a new developer comes into the system, they may be tempted to remove that gate. After all, it’s not doing anything, right?

Well… How do you know?

The trouble is, you don’t and you can’t know with certainty, not without Test Driven Development. Delete some code and if all the tests still pass, the code wasn’t needed.*

Funny enough if you use TDD, you’ll be regularly deleting code enough to not have to worry about Chesterton’s fence.

There is immense value in this approach for your team. When production bugs are as easy as deleting a required setting that people thought wasn’t being used, it’s critical to ensure you have a style of development that keep these freak, costly accidents from happening in your code base. Yes, your code may just be an internal financial dashboard for an insurance company; but if that dashboard goes down, can your insurance agents still sell insurance?

*there are a lot of ins, outs, and what-have-yous with this (like using a FauxO style of TDD so you don’t have to necessarily worry about lots of integration test paths; but still having integration tests to cover the boundaries, like network IO, disk IO, and the user interface)

P.S. I offer virtual team TDD immersion training for .NET teams. During this time when your team may be experiencing a lull due to global events, think about using this training as a way to keep your teams sharp and ensure you can deliver software reliably and consistently to your stakeholders. Learn more at https://www.doubleyourproductivity.html/paid.html

Abstractions Carry a Cost

Abstractions have a cost. Your project, team, and you will carry the cost of that abstraction for its lifetime.

We don’t like to say that, because as developers we love abstractions, but every single abstraction carries a cost, and that cost affects everyone that develops, tests, or uses the application.

Most of the time, we believe (or it is demonstrable that) these abstractions provide more value than they cost.

Sometimes we do this without any evidence that that’s the case.

I was reviewing a codebase recently and most of the codebase was T4 template generated. Every controller and model was generated from a T4 template; with logic inside those templates that through user input determined what was generated and how it was generated.

I have no doubt when these abstractions were introduced, the team thought they’d save lots of time.

One year later, that application is no longer maintained; and in fact, within a few months of release it was no longer maintained.

What sort of value did they get out of a complex abstraction for only 3 months of maintaining it?

It’s hard to tell, but my immediate guess is “not much”.

Abstractions have a cost.

In another project I worked on, the firmware for Jewelbots, there were almost no abstractions. While I had the privilege to have an SDK to use for the System-On-Chip we sourced for our Jewelbots, there were breaking changes every release, and the little abstractions that were present would wildly change. I was so close to the metal that I would have wished for an abstraction or ten.

Where’s the balance?

First off, if someone says “this abstraction will save us X time”, you should ask them to prove it before implementing it system wide. That seems a bit adversarial, so maybe there’s an easier way?

We talk about software design as this abstract thing; divorced from the day to day realities of software development. We treat software as if we’re in the frontier west, living out of wagons and running from one gold rush to the next. We’re so busy adding on what we might need that we forget what we do need: Software that we know works. Software that we know we can change without having to rewrite it because it’s too complex to change. What we’ve forgotten is that while we treat goldrush software as an ideal, we’re asking billions of people to put their trust in our software. We build abstractions that don’t make things better for our customer, and only make things marginally better for ourselves, while ignoring the concepts that will help both ourselves and our customers.

If you’re willing to spend 3 months on code generation, or 3 months on some fancy Entity-Attribute-Value machination that makes it ‘easier to add new features without a database update’ (God help us all), you should be willing to build your software through Test Driven Development. Not only will your software come out better designed, and with fewer bugs, but you’ll also achieve a balance to the abstractions you want to create; by creating abstractions that are easily testable (and thus, easy to change).

Taking the Guesswork out of Estimation

I don’t know about you, but I am terrible at software estimates.

I’m even worse if I haven’t done that thing before, whatever that *thing* is.

As a recent example, a client (for the near term I still accept project work in .NET and Angular on the side, while growing this business) needed me to implement an editor for their workflow (editor here means a WYSIWYM editor like a markdown editor).

Complicating matters is that Angular is very particular about how you can interface with third party libraries; so you end up needing to use or create a wrapper.

Complicating matters further, if you use a design system like the Material CDK, you also want to wrap that wrapper in something that implements the Material design constraints.

All this for a content editor!

If I didn’t know this, it would have thrown off my estimate a lot. And logically, it’s not something that should ever happen. It’s illogical to require these hoops to implement a text editor in angular, and if you’re not intimately familiar with the issues at play, (as a business person probably would not be), it’s easy to wonder why it should take more than a day to implement a text editor in Angular. Or, as this XKCD brilliantly illustrates:

So what to do?

If your system hasn’t been created through TDD, you’ll get some measure of success in estimating by making the change and seeing what tests break. In the case where you have good test coverage, you lower the amount of parts you have to guess will change, and guessing is what makes estimation so hard.

In a system created through TDD, it’s even easier as your tests will not be coupled to the specific things you’re tied to (like a text editor), rather they’ll be tied to the operations your system makes on that text editor; allowing you to swap out editors and *knowing* for certain if it affects the operation of your system.

I offer team based immersion training for TDD; both online and in person, where you’ll learn just how to do this. To get started, visit https://doubleyourproductivity.io/paid.html.

“We don’t need TDD, our project isn’t worth it”

In 2018 I converted our garage into a bedroom, laundry room, and entryway. I enlisted the help of tradespeople (a mason, plumber, and electrician) to handle the exterior, plumbing moves, and electrical needs (respectively), but I did the rest myself.

It took me a year from plan to being finished, and I finished the day before Thanksgiving.

It was hard, possibly the hardest non-tech thing I’ve ever done. I know the software world pretty well, having worked across tech stacks, industries, team types, and methodologies — I feel like I understand technology. It is not a surprise to say I definitely do not understand the home remodeling world.

To get ready for this fact, I did a ton of research. I looked up building codes and realized an entirely different lexicon was at play (somewhat related, but the word “shed” doesn’t exist in our county’s building code — the appropriate word is “accessory structure”), I watched Youtube videos, and I asked people who had done this work before.

As it stood, I still failed inspection a few times, because my research hadn’t taken into account some unique nature of the space’s transition. For instance, I should have probably outsourced the subfloor construction; since I needed to raise and level the floor about 1.5 inches at one end, and 5 inches at another. I made it work, but I’m pretty sure a professional would have done it faster and it would have been better constructed.

Why didn’t I engage a professional? I mistakingly thought I’d save money by not contracting that part out. That somehow, a floor that I will walk on for the rest of the time we live in this house didn’t need the care of a professional. It was Good Enough Of course, as I found out later, I just hadn’t done enough research. But at the time, I spent around 2 months (I could only devote nights and weekends to it) raising and leveling the floor. If I had engaged with a professional, it would have been done in less than a week. This is about the only regret I have about that project. The floor isn’t quite level in one corner, and because I didn’t insulate what I raised, it’s a bit hollow sounding and a little colder than it should be.

You ever have a software project like this? One where you think “we’ll do it right this time”, but that one (or more) stakeholder says “this will be good enough”, and you acquiese? After all, how bad could it be?

It couldn’t be any worse than a floor with an unlevel corner that dips down a little bit, and a chilly floor in the winter, right?

We treat internal software projects (or sometimes, consulting projects) just like I treated the floor in my garage renovation, and contrary to the beliefs we hold, it shows. It affects us.

For your next garage renovation software project, think about whether you want it to be like your last few projects. Do you want there to be an unlevel floor? Do you want to dislike the floor in the winter? If not, then you’ll want to focus on practices that will help you deliver a project on time, that users can use without asking “What happened to this floor?”

P.S. I offer virtual team TDD immersion training for .NET Software teams. This training helps your team learn Test Driven Development, together, and ensures the entire team develops a shared understanding of the processes, reliable outcomes, and aims of TDD for your codebase. To get started, visit https://www.doubleyourproductivity.io/paid.html to learn more and on how to book a session.

“You Got the Job, Now what?” (Part 2) – Webinar

I appeared on an Apex Systems sponsored webinar titled: “You got the job, now what?” (Part 2). This webinar aired on February 25, 2020.

Part 1 is also available for your perusal (sorry for the reg-wall; I don’t control that).

In Part 2, I joined two career experts to talk about what happens after you join a new company, and how to be and bring your best self to that table.

I really enjoyed this segment, and learned quite a bit. I hope it helps you too.