#CodeIsCommunication: The Value of Constrained Choices in Code

Building software is expensive. But the biggest cost is not writing the new code—it’s understanding the existing code. So how do we optimize for that cost? By making the code communicate.

The more that code is written to be intuitive, readable, and harder to misunderstand, the faster another developer can understand it. And this means they have more time for delivering new features more quickly.

In this series of #CodeIsCommunication posts, I’ll share concepts and techniques to help drive down the cost of software by making it easier to understand—by making it communicate.

Pop-quiz: What is George Washington’s birthdate?

A. April 3, 2021

B. December 20, 1312

C. February 22, 1732

D. March 10, 1100

Even if you are not a historical expert, I’d guess you probably picked C without even having to look it up. Why? Because none of the other options are reasonable.

Contrast with this question: Fill in the blank—Abraham Lincoln’s birthdate is ____.

This question is much harder to answer, right? I’d guess the vast majority of you reading this (including myself) would have to look this up.

The first question is so much easier to answer because out of the four available options, we can rule out three. Whereas the second question has thousands of potential answers. Because our choices are not constrained, we can’t answer the second question as easily.

Put another way, when we make it hard to pick the wrong choices and easy to pick the right ones, we create pits of success.

Much like the questions above, when you read code it asks you to understand it. And if the code has constrained choices, we can understand it faster and get started writing the new code.

For example, take this class:

public OrderDto {
  public OrderType Type {get; set;}}

Question: When an OrderDto is created, can the Type field be null?

If you are writing a function that takes in the OrderDto and checks the Type field, you have to ask that question. You could try to be defensive and add a null check, but then what? Some default value? An exception? So you go researching and digging to understand if the field will ever be null and how to handle it.

Compare that with this version:

public OrderDto {
  public OrderDto(OrderType type, …) {
    if(type == null) throw new Exception();
    Type = type;} 
  public OrderType Type {get; private set;}}

Question: When an OrderDto is created, can the Type field be null?

No! Never! The constructor enforces this constraint. Instead of spending the time to dig into existing usages, you can spend that time on our shiny new function and be confident that the Type field will always be there (If you code in C#, from C#8 there are nullable properties that let you enforce the same/similar constraint without having to rely on constructor syntax. This is a huge win if you favor object initializer syntax.).

If you had to work with those two versions of the OrderDto object, which one do you prefer? If you picked the second version, then you understand how constraining choices can help the code communicate. And the better it communicates, the faster you can understand it and write new code.

There are many techniques to constrain choices, from interface constraints, to encapsulation, to immutability. One way or another, make the code communicate. Make the code guide people away from the wrong choices and lead them to the right choices. Because #CodeIsCommunication.

39 views0 comments

Recent Posts

See All